6

Ich habe eine Weile daran fest, und mir gingen die Ideen aus, helfen geschätzt!Iterating variadic Vorlagentypen

Die folgenden Segmente sind Beispielcode, um zu vereinfachen.

gelten folgende Voraussetzungen:

class Base; 
class DerivedA : public Base; 
class DerivedB : public Base; 

und diese:

class Manager { 
public: 
    std::map<std::type_index, Base*> container; 

    template<typename ...T> 
    void remove() { 
     // Iterate through templates somehow and... 
     container.erase(typeid(T)); 
    } 
} 

Im Grunde bin ich zu speichern, in einem Behälter, eindeutige Instanzen von abgeleiteten Klassen, durch die std :: type_index als Schlüssel. Erlauben mir, wie etwas zu tun:

manager.remove<DerivedA>(); 

das gesagt ist, würde ich in der Lage sein mag, das Gleiche zu tun, sondern können mehrere Vorlagen mehrere Instanzen direkt auf einmal zu entfernen, wie zum Beispiel:

manager.remove<DerivedA, DerivedB>() 

ich weiß, es möglich ist, durch variadische Vorlagen iterieren als here beschrieben, aber ich halte Kompilierungsfehlern bekommen ...

error C2440: 'initializing': cannot convert from 'initializer-list' to 'std::initializer_list'

error C3535: cannot deduce type for 'auto' from 'initializer-list'

... wenn ich versuche, diesen Code auszuführen :

template<typename ...T> 
void remove() { 
    // Iterate through templates somehow and... 
    auto list = {(container.erase(typeid(T)))... }; 
} 

Irgendwelche Ideen? Vielen Dank.

+2

'int dummy [] = {(c.resease (typeid (T)), 0) ...};' –

+0

Woah, Ihre Lösung funktionierte perfekt direkt aus der Box ... Ich habe etwas ähnliches versucht früher, aber ohne die 0. Was ist der Unterschied? –

+0

'0' ist ein' int'. –

Antwort

2

Ich schätze, Sie sind gerade in einen MSVC-Fehler geraten. Der Kompilierfehler:

error C3535: cannot deduce type for 'auto' from 'initializer-list'

ist nicht gültig. C++ 11 erlaubt Abzug von auto von braced-init-Liste, solange alle Typen gleich sind. In Ihrem Fall gibt std::map::erase einen size_t zurück, also sollte es kompilieren. Here ist ein Beispiel mit Ihrem Code.

Um das zu bekommen, können Sie nur in der Lage sein, explizit die Art zu schaffen:

size_t dummy[] = {m.erase(typeid(T))...}; 

Oder, falls jemand in keiner Art geht, prepend eine Null:

size_t dummy[] = {0u, m.erase(typeid(T))...}; 

That So wird das Array immer mindestens ein Element haben. Je mehr typische Verwendung, die Kerrek in seinem Kommentar vorgeschlagen, würde die folgende sein:

int dummy[] = {0, (void(m.erase(typeid(T)), 0)... }; 

, dass unabhängig von dem Ausdruck arbeitet, die Sie mit m.erase(...) ersetzen werden, da der Wert von (..., 0)0 ist. Die void ist da, um Probleme mit der Überlastung operator, zu vermeiden.

+0

abzuleiten Ah ja, ich sehe, macht Sinn. Ich habe mich gefragt, warum es nicht kompiliert werden würde, weil es genauso war wie die Lösungen anderer. Danke für das Aufklären. –