2014-10-30 2 views
0

У меня следующий пример TestC - это класс шаблона. Тест класса использует шаблонный шаблон в качестве шаблона, и существует специальный член_, который является вложенным экземпляром A>. Однако жалоба компилятора на этот вопрос. Это незаконно? Или как его исправить?Как работает класс вложенных шаблонов C++?

Заранее спасибо

#include <iostream> 
using namespace std; 

template <class A> 
class TestC { 
    public: 
    TestC(double a = 100.0) : a_(a) {}; 
    A member_; 
    double a_; 
}; 

template <template <class> class A> 
class Test { 
    public: 
    Test(A<Test<A> > member = A<Test<A> >()); 
    A<Test<A> > member_; 
}; 

int main() { 
    TestC< Test<TestC> > a(10.0); 
    return 0; 
} 

Compilation error time: 0 memory: 3292 signal:0prog.cpp: In instantiation of ‘class Test’: prog.cpp:8:7: required from ‘class TestC >’ prog.cpp:21:23: required from here prog.cpp:16:17: error: ‘Test::member_’ has incomplete type A > member_; ^prog.cpp:5:7: error: declaration of ‘class TestC >’ class TestC {

^
+0

Я предполагаю, что вы имели в виду 'TestC < Test> а; ', поскольку это означает вы объявляете функцию с именем' a'. – user657267

+0

, если я изменил, например. TestC < Test> a (10,0); Я думаю, что я строю объект TestC < Test>, все еще ошибка. – David

ответ

1

Класс

template <template <class> class A> 
class Test { 
    public: 
    Test(A<Test<A> > member = A<Test<A> >()); 
    A<Test<A> > member_; 
    //^^^^^^^ this requires Test to be defined completely. 
}; 

аналогично

class Test 
{ 
    Test member_; 
}; 

Definitio n из class Test не заканчивается, прежде чем вы определяете переменную-член, которая зависит от полного определения класса.

В обычном классе вы можете использовать указатель на класс в качестве члена.

class Test 
{ 
    Test* member_; 
}; 

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

#include <iostream> 
using namespace std; 

template <class A> 
class TestC { 
    public: 
    TestC(double a = 100.0) : a_(a) {} 
    A member_; 
    double a_; 
}; 

template <template <class> class A> 
class Test { 
    public: 
    Test() {} 
    A<Test<A>* > member_; 
}; 

int main() { 
    TestC< Test<TestC> > a; 

    // type of a is TestC< Test<TestC> > 
    // It has a member member_. 
    // type of a.member_ is Test<TestC> 
    // a.member_ has a member member_ 
    // type of a.member_.member_ is TestC<Test<TestC>*> 
    // a.member_.member_ has a member whose type is Test<TestC>* 
    // You can assign nullptr to it. 
    a.member_.member_.member_ = nullptr; 

    // Or you can assign to it a pointer to an object allocated from the heap. 
    a.member_.member_.member_ = new Test<TestC>; 

    return 0; 
} 
+0

Спасибо. Однако изменить на указатель не то, что я мог бы сделать. – David

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