Необходимо на самом деле определить статического участника где-нибудь (после определения класса). Попробуйте это:
class Foo { /* ... */ };
const int Foo::MEMBER;
int main() { /* ... */ }
, Который должен избавиться от неопределенной ссылки.
Проблема возникает из-за интересного столкновения новых функций C++ и что Вы пытаетесь сделать. Во-первых, давайте смотреть на push_back
подпись:
void push_back(const T&)
Это ожидает ссылку на объект типа T
. Под старой системой инициализации существует такой участник. Например, следующий код компилирует очень хорошо:
#include <vector>
class Foo {
public:
static const int MEMBER;
};
const int Foo::MEMBER = 1;
int main(){
std::vector<int> v;
v.push_back( Foo::MEMBER ); // undefined reference to `Foo::MEMBER'
v.push_back( (int) Foo::MEMBER ); // OK
return 0;
}
Это вызвано тем, что существует фактический объект где-нибудь, которому сохранили то значение в нем. Если, однако, Вы переключаетесь на новый метод определения, что статические участники константы, как Вы имеют выше, Foo::MEMBER
больше не объект. Это - константа, несколько сродни:
#define MEMBER 1
, Но без головных болей макроса препроцессора (и с безопасностью типов). Это означает, что вектор, который ожидает ссылку, не может получить тот.
Стандарт C++ требует определения для Вашего статического участника константы, если определение так или иначе необходимо.
определение требуется, например, если это - адрес, используется. push_back
берет его параметр ссылкой константы, и таким образом, строго для компилятора нужен адрес Вашего участника, и необходимо определить его в пространстве имен.
при явном кастинге константы Вы создаете временный файл, и это - этот временный файл, который связывается со ссылкой (по специальным правилам в стандарте).
Это - действительно интересный случай, и я на самом деле думаю, что стоит поднять вопрос так, чтобы станд. быть измененным для имения того же поведения для постоянного участника!
, Хотя, в странном способе это могло рассматриваться как законное использование унарного '+' оператор. В основном результатом эти unary +
является rvalue и таким образом, правила для привязки rvalues к ссылкам константы применяются, и мы не используем адрес нашего статического участника константы:
v.push_back( +Foo::MEMBER );
Никакая идея, почему бросок работает, но Foo:: УЧАСТНИК не выделяется до первого раза Foo загружается, и так как Вы никогда не загружаете его, он никогда не выделяется. Если бы у Вас была ссылка на Нечто где-нибудь, это, вероятно, работало бы.