2016-04-29 11 views
1

私はC++のテンプレートを少し前に作っています:curiously recurring template patternのいくつかの非常に基本的な例は数学的なクラスのクラスです。今回は、同じパターンを使って、自分自身を追加して他のオブジェクトを見回すことができるクラスのオブジェクトのリストまたは "ネットワーク"を作成しようとしました。私は静的なstd :: listを使ってこれを行うことができると思った。だから、私の試みは、このように書き:クラスメンバーリストのためのC++テンプレートの構築

template<class C> class HasNetwork{ 
    public: 
    HasNetwork(){} 
    static list<C*> m; 
}; 
template<class C> list<C*> HasNetwork<C>::m = list<C*>(); 
class IHaveNetwork: public HasNetwork<IHaveNetwork>{ 
    public: 
    IHaveNetwork(){ m.push_back(this); } 
}; 
int main(){ 
    IHaveNetwork lHF, lHF2; 
    //for(list<IHaveNetwork*>::iterator it = lHF.m->begin(); ; it++); 
    return 0; 
} 

コンパイルするようだが、私は(さえコメントアウトループの反復子を持つ)厄介なリンクエラーが発生します。たぶん私はいくつかのキャストを行う必要がありますか、またはおそらく "これは"コンストラクタが終了するまで定義されていない?

/tmp/templatest-912860.o: In function `__clang_call_terminate': 
templatest.cpp: 

(.text.__clang_call_terminate[__clang_call_terminate]+0x9): undefined reference to `__cxa_begin_catch' 


templatest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()' 


/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*> 

>::deallocate(std::_List_node<IHaveNetwork*>*, unsigned long)': 

templatest.cpp:

(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m]+0x1c): undefined reference to `operator delete(void*)' 

/tmp/templatest-912860.o: In function `std::list<IHaveNetwork*, std::allocator<IHaveNetwork*> 

>::_M_insert(std::_List_iterator<IHaveNetwork*>, IHaveNetwork* const&)': 

templatest.cpp:

(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_]+0x31): undefined reference to 

`std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)' 

/tmp/templatest-912860.o:機能でここ

は、リンクエラーです`std :: list> :: _ M_create_node(IHaveNetwork * const &) ': templatest.cpp:

(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xa0): undefined reference to `__cxa_begin_catch' 

templatest.cpp:(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xbb): undefined reference to `__cxa_rethrow' 
templatest.cpp:  

(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xce): undefined reference to `__cxa_end_catch' 

/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*> >::allocate(unsigned long, void const*)': 

templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x33): undefined reference to `std::__throw_bad_alloc()' 

templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x40): undefined reference to `operator new(unsigned long)' 

/tmp/templatest-912860.o:(.eh_frame+0x13):私は再現することはできません `__gxx_personality_v0'

+0

くそ:ここ

はあなたのリンクをコンパイルし、(私はいくつかの間接レベルのエラーを修正する必要がありました)も、警告なしで実行されるコードを少し変更したバージョンですタイプミスの人に申し訳ありません。 – mathreadler

+0

私はそれを試した[ここ](http://rextester.com/BDJL98512)はうまくいくようです。 – songyuanyao

+0

はい、うまくコンパイルされますがリンクしません。多分私は何とかリストにリンクする必要がありますか? – mathreadler

答えて

1

への未定義参照。私は助けのためにあなたをupvoteことを約あった

#include <iostream> 
#include <list> 
#include <string> 

template<class C> class HasNetwork{ 
    public: 
    HasNetwork(){} 
    static std::list<C*> m; 
}; 
template<class C> std::list<C*> HasNetwork<C>::m = std::list<C*>(); 
class IHaveNetwork: public HasNetwork<IHaveNetwork>{ 
    std::string name; 
    public: 
     IHaveNetwork(const std::string &name): name(name) { m.push_back(this); } 
     std::string getName() const { 
      return name; 
     } 
}; 
int main(){ 
    IHaveNetwork lHF("foo"), lHF2("bar"); 
    for(std::list<IHaveNetwork*>::iterator it = lHF.m.begin(); it != lHF.m.end(); it++) { 
     std::cout << (*it)->getName() << std::endl; 
    } 
    return 0; 
} 
+0

コンパイルとリンクのためにどの行を実行しますか? – mathreadler

+0

argh nooo、私はg ++の代わりにgccを使用していました。今あなたのコードは完全に動作します。助けをありがとう。 – mathreadler