2015-01-29 3 views
3

я наткнулся на некоторые C++ 11 код, который выглядит следующим образом:constexpr статический член против переменной

// some_file.h 
namespace blah { 
    class X { 
    public: 
    constexpr const static std::initializer_list<uint64> SOME_LIST = 
     {1,2,3}; 
    }; 
} 

// some_file.cpp 
#include "some_file.h" 
namespace blah { 
    constexpr const std::initializer_list<uint64> X::SOME_LIST; 
} 

Что компилируется нормально. Я предполагаю, что определение в файле cpp используется, чтобы избежать дублирования символов в каждом файле, который включает заголовок (пожалуйста, исправьте меня, если я ошибаюсь).

Затем я попробовал следующее:

// my_file.h 
namespace bleh { 
    constexpr const static char SOME_CONSTANT[] = "yay"; 
} 

// my_file.cpp 
#include "my_file.h" 
namespace bleh { 
    // if I add this or any other variation, compilation breaks! 
    //constexpr const static char SOME_CONSTANT[]; 
} 

Код выше не работает, если я добавить явное определение в файле .cpp. Поэтому мне интересно: есть ли дублирование символов во втором случае? Если да, существует ли способ определить переменную без охватывающего класса?

+2

'constexpr const X :: SOME_LIST;' отсутствует спецификатор типа. Вы уверены, что это код, который скомпилирован? – typ1232

+0

@ typ1232 извинения, я написал код без собственно компиляции, но я искал образец, который компилируется. –

ответ

2

В static ключевые слова означают две разные вещи здесь:

Когда вы объявляете переменную или функцию в области видимости файла (глобальные и/или имен сфера), статическое ключевое слово указывает, что переменная или функция имеет внутреннюю связь. Когда вы объявляете переменную, переменная имеет статическую продолжительность, и компилятор инициализирует ее до 0, если вы не укажете другое значение.

Когда вы объявляете элемент данных в объявлении класса, ключевое слово static указывает, что одна копия члена разделяется всеми экземплярами класса. Статический член данных должен быть определен в области файлов. Интегрированный элемент данных, который вы объявляете как const static, может иметь инициализатор.

C++ вам нужно определить статические члены класса где-то, потому что символ класса является глобальным (и ваш член). Это невозможно сделать в заголовке из-за нескольких определений.

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

+0

Есть ли способ иметь глобальный символ во втором случае? Должен ли я просто добавить класс в этом случае, чтобы обеспечить его соблюдение? –

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