2016-02-03 3 views
3

Я знаю, что элементы статического литерала могут быть инициализированы в определении класса, а нелитеральные типы не могут.const статический член инициализация - внутри vs определение внешнего класса

class Class 
{ 
    static const int lt = 0; //OK 
    static const std::string nlt = "hello"; //compilation error 
}; 

Однако, я побежал в странный вопрос, где я не могу использовать элементы в STL контейнеров, если они инициализируются внутри определения класса, в отличие от внешней стороны.

class Class 
{ 
public: 
    static const int var = 1; 
    void f(); 
}; 

void Class::f() { 
    std::vector<int> vec; 
    vec.push_back(var); 
} 

В приведенном выше примере, приводит к ошибке компоновщика undefined reference to Class::var Если переместить инициализацию снаружи, ошибка исчезнет.

const int Class::var = 1;

Каковы различия между этими двумя инициализациями выше? Почему возникает ошибка с контейнерами stl?

ответ

4

В чем разница между двумя инициализациями выше? Почему возникает ошибка с контейнерами stl?

Тип аргумента std::vector<int>::push_back() is int const&. Всякий раз, когда переменная используется ссылкой или указателем, она должна быть определена.

Простое изменение на Class::f Осуществление избавит вас от необходимости определять Class::var.

void Class::f() { 
    std::vector<int> vec; 
    int v = var; 
    vec.push_back(v); 
} 

Здесь var не используется в качестве ссылки. Следовательно, нет необходимости определять Class::var.

+0

Спасибо. Кроме того, определение его вне класса с инициализацией в декларации работает 'const int Class :: var;' Это позволяет получить ясность значений в заголовке, но на него все еще можно ссылаться. – Ramon

+0

@Ramon, все верно. –

+0

Кроме того, создание временного 'vec.push_back ((int) var)' довольно читаемо и не нуждается в определении. – Ramon

Смежные вопросы