2013-08-13 5 views
7

Например, я хотел иметь переменную типа auto, потому что я не уверен, какой тип она будет.Возможно ли иметь переменную-член «auto»?

Когда я пытаюсь объявить его в классе/декларации STRUCT это дает мне эту ошибку:

Cannot deduce auto type. Initializer required

Есть ли способ вокруг него?

struct Timer { 

    auto start; 

}; 
+1

фигуру из своего типа –

+4

Не то, что шаблоны для? – user1520427

+0

Когда вы узнаете, какой тип он будет? Время компиляции или время выполнения? Можете ли вы дать нам какой-то контекст? Что ты пытаешься сделать? – Homer6

ответ

20

Вы можете, но вы должны объявить его static и const:

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

A working example in Coliru.

При таком ограничении вы поэтому не можете иметь start как нестатический член и не можете иметь разные значения в разных объектах.

Если вы хотите различные типы start для различных объектов, лучше иметь свой класс как шаблон

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

Если вы хотите вывести тип T, вы можете сделать на заводе, как функцию, которая делает то типа.

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

Это то, что C++ draft standard должен сказать об использовании auto для переменных-членов, в разделе пункт 47.1.6.4 auto specifier:

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).

Поскольку он должен быть инициализирован это также означает, что он должен быть const. Так что-то вроде следующего будет работать:

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

Я не думаю, что получает вас слишком много, хотя, используя шаблон как Марк говорит или теперь, когда я думаю об этом еще немного, может быть, вам просто нужно Variant Type в том случае, вы должны проверить Boost.Variant или Boost.Any.

1

№. Каждый конструктор может иметь свой собственный инициализатор для start, поэтому не может быть согласованного типа.

Если вы сделать есть полезное выражение, вы можете использовать это:

struct Timer { 

    Foo getAFoo(); 

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

    Timer() : start(getAFoo().Bar()) { /***/ } 
}; 
Смежные вопросы