2013-08-13 2 views
7

Zum Beispiel wollte ich eine Variable vom Typ auto haben, weil ich nicht sicher bin, um welchen Typ es sich handelt.Ist es möglich, eine "Auto" -Membervariable zu haben?

Wenn ich versuche, es zu erklären, in Klasse/Struktur Deklaration es gibt mir diese Fehlermeldung:

Cannot deduce auto type. Initializer required

Gibt es eine Möglichkeit, um es?

struct Timer { 

    auto start; 

}; 
+1

Figur aus seiner Art –

+4

Ist das nicht was Vorlagen für sind? – user1520427

+0

Wann finden Sie heraus, um welchen Typ es sich handelt? Kompilierzeit oder Laufzeit? Kannst du uns einen Zusammenhang geben? Was versuchst du zu machen? – Homer6

Antwort

20

können Sie, aber Sie müssen es static erklären und const:

struct Timer { 
    static const auto start = 0; 
}; 

A working example in Coliru.

Mit dieser Einschränkung können Sie daher start nicht als statisches Element verwenden und keine unterschiedlichen Werte in verschiedenen Objekten haben.

Wenn Sie verschiedene Arten von start für verschiedene Objekte wollen, müssen besser Ihre Klasse als Vorlage

template<typename T> 
struct Timer { 
    T start; 
}; 

Wenn Sie die Art von T ableiten wollen, können Sie ab Werk eine ähnliche Funktion machen, dass das tut Typ Abzug.

template<typename T> 
Timer<typename std::decay<T>::type> MakeTimer(T&& startVal) { // Forwards the parameter 
    return Timer<typename std::decay<T>::type>{std::forward<T>(startVal)}; 
} 

Live example.

3

Dies ist, was die C++ draft standard etwa für Membervariablen mit auto zu sagen hat, in Abschnitt 7.1.6.4 auto specifier Absatz 4:

The auto type-specifier can also be used in declaring a variable in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.4.2).

Da es dies auch initialisiert werden muss, bedeutet, dass es const sein muss. So etwas wie das folgende funktioniert:

struct Timer 
{ 
    const static int start = 1; 
}; 

Ich glaube nicht, dass Sie zu viel wird allerdings Vorlage als Mark schlägt vor, oder jetzt, dass ich darüber nachdenke einige mehr vielleicht brauchen Sie nur ein Variant Type in diesem Fall Sie sollten Boost.Variant oder Boost.Any überprüfen.

1

Nein. Jeder Konstruktor könnte seinen eigenen Initialisierer für start haben, daher könnte kein konsistenter Typ verwendet werden.

Wenn Sie einen brauchbaren Ausdruck zu tun haben, können Sie diese verwenden:

struct Timer { 

    Foo getAFoo(); 

    delctype(Timer().getAFoo().Bar()) start; 

    Timer() : start(getAFoo().Bar()) { /***/ } 
};