Как получить размер аргумента шаблона при использовании CRTP? - PullRequest
7 голосов
/ 17 декабря 2011

В VC ++ 10 следующий пример завершается с ошибкой C2027: «использование неопределенного типа« X »».Однако g ++ 4.6 это прекрасно компилирует.

template<class T>
class C
{
    static const size_t size = sizeof(T);
};

class X : public C<X> { };

Так какой же из них правильный?И как мне сделать это так, чтобы он работал на основных компиляторах?

Это не так уж и сложно, потому что VC ++ все еще допускает sizeof (T) внутри функций-членов C. Я просто должен повторить некоторые определения длинных типовчто раздражает.

РЕДАКТИРОВАТЬ: Я понимаю, что мой пример был плохим, потому что я действительно хотел использовать размер в качестве постоянной времени компиляции, таким образом:

template<size_t size> class C2 { };

template<class T>
class C
{
   typedef C2<sizeof(T)> A;
};

class X : public C<X> { };

Оба компилятора отвергают это, поэтому я предполагаю, что это, вероятно, невозможно, но, как я уже сказал, я все еще могу использовать sizeof внутри функций.Я просто надеялся, что мне не придется повторять typedef внутри каждой функции.

template<size_t size> class C2 { };

template<class T>
class C
{
    void foo() { typedef C2<sizeof(T)> A; }
};

class X : public C<X> { };

1 Ответ

6 голосов
/ 17 декабря 2011

Статический член не может быть инициализирован в самом классе, поскольку тип T определен и еще не завершен.

Однако вы можете инициализировать его вне класса как:

template<class T>
class C
{
    static const size_t size;
};

template<typename T>
const size_t C<T>::size = sizeof(T); //initialization of the static member

Должно скомпилироваться нормально: http://ideone.com/6sNgN

...