Инициализация статических членов шаблонного класса - PullRequest
6 голосов
/ 08 сентября 2010

Я пытаюсь выяснить, почему этот пример не компилируется. Насколько я понимаю, если статическая переменная не установлена ​​явно, то по умолчанию она равна 0. В пяти приведенных ниже примерах четыре из них ведут себя так, как я ожидал, но закомментированная не компилируется.

#include <iostream>
class Foo
{
public:
    static int i;
    static int j;
};
template <int n>
class Bar
{
public:
    Bar(int) { }
    static int i;
}; 

static int i;
int Foo::i;
int Foo::j = 1;
template <> int Bar<2>::i;
template <> int Bar<3>::i = 3;

int main(int argc, char** argv)
{
    std::cout << "i         " << i << std::endl;
    std::cout << "Foo::i    " << Foo::i << std::endl;
    std::cout << "Foo::j    " << Foo::j << std::endl;
    //std::cout << "Bar<2>::i " << Bar<2>::i << std::endl; // Doesn't compile?
    std::cout << "Bar<3>::i " << Bar<3>::i << std::endl;
    return 0;
}

Почему int Bar<2>::i не делает то же самое, что int Foo::i или static int i?

Редактировать: я забыл добавить шаблон <> в объявления Bar <2> и Bar <3>. (проблема не решается, но все еще возникают ошибки компоновщика)

Ответы [ 2 ]

5 голосов
/ 08 сентября 2010

В соответствии с правилами текущего стандарта C ++ специализация template <> int Bar<2>::i; является только объявлением, а не определением.Чтобы стать определением, вы должны указать инициализатор.(См. Пункт 14.7.3 / 15)

Кроме этого, вы упустили один очень распространенный случай: определение неспециализированного статического члена шаблона:

template <int n> int Bar<n>::i;

Thisдает определение для Bar<N>::i для N, не равное 2 или 3.

1 голос
/ 08 сентября 2010

В соответствии с последним проектом стандарта C ++ говорится:

14.7.3 / 13 Явная специализация статического члена данных шаблона является определением, если объявление включает инициализатор;в противном случае это объявление.
[Примечание: определение статического члена данных шаблона, который требует инициализации по умолчанию, должен использовать фигурный список инициализации:

 template<> X Q<int>::x;       //declaration
 template<> X Q<int>::x ();    // error: declares a function
 template<> X Q<int>::x { };   // definition

- конец примечания]

То, что вы спрашиваете, возможно, если ваш компилятор его поддерживает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...