こんにちは。タイトル通りですが、入れ子になったテンプレートクラスのメンバ関数の特殊化の方法が分かりません。。。
c++
1#include <iostream> 2 3// コンテナクラス 4template <class T> class container 5{ 6public: 7 // イテレータの種類をクラス名で表す 8 struct normal_iterator_type; 9 struct hoge_iterator_type; 10 struct hogehoge_iterator_type; 11 12 // イテレータのテンプレート 13 template <typename iterator_type> struct template_iterator 14 { 15 // 共通の処理 16 void shared_func() 17 { 18 std::cout << "template_iterator::shared_func()" << '\n'; 19 } 20 21 // 個別の処理 22 void individual_func() 23 { 24 std::cout << "template_iterator::individual_func()" << '\n'; 25 } 26 }; 27 28 using iterator = template_iterator<normal_iterator_type>; 29 using hoge_iterator = template_iterator<hoge_iterator_type>; 30 using hogehoge_iterator = template_iterator<hogehoge_iterator_type>; 31 32 // イテレータ取得関数 33 iterator begin(); 34 hoge_iterator begin_hoge(); 35 hogehoge_iterator begin_hogehoge(); 36}; 37 38/** 39 * イテレータ取得関数の定義 40 */ 41template <class T> 42typename container<T>::iterator container<T>::begin() 43{ 44 return container<T>::iterator(); 45} 46 47template <class T> 48typename container<T>::hoge_iterator container<T>::begin_hoge() 49{ 50 return container<T>::hoge_iterator(); 51} 52 53template <class T> 54typename container<T>::hogehoge_iterator container<T>::begin_hogehoge() 55{ 56 return container<T>::hogehoge_iterator(); 57} 58 59// /** 60// * 個別処理関数の特殊化 61// */ 62template <class T> 63template <> 64void container<T>::iterator::individual_func() 65{ 66 std::cout << "iterator::individual_func()" << '\n'; 67} 68 69template <class T> 70template <> 71void container<T>::hoge_iterator::individual_func() 72{ 73 std::cout << "hoge_iterator::individual_func()" << '\n'; 74} 75 76template <class T> 77template <> 78void container<T>::hogehoge_iterator::individual_func() 79{ 80 std::cout << "hogehoge_iterator::individual_func()" << '\n'; 81} 82 83int main(int argc, char const *argv[]) { 84 85 container<int> ctn; 86 auto itr = ctn.begin(); 87 auto itr_hoge = ctn.begin_hoge(); 88 auto itr_hogehoge = ctn.begin_hogehoge(); 89 90 itr.shared_func(); 91 itr_hoge.shared_func(); 92 itr_hogehoge.shared_func(); 93 itr.individual_func(); 94 itr_hoge.individual_func(); 95 itr_hogehoge.individual_func(); 96 97 return 0; 98} 99
上記はいま作っているコンテナクラスの簡単なモデルです。イテレータを数種類持たせたいのですが、すべてに対してクラスを作るとコードが多くなってしまうので、イテレータのテンプレートを1つ作って、共通の機能(++,--,==等)はテンプレートクラス内に書き、個別の機能は、イテレータの種類によって挙動の変わる関数を特殊化して、コード量を減らそうと思ったのですが、その特殊化の部分が上手く行きません。(以下コンパイル結果)
xxx@xxx-HP-Notebook:~/dev/cpp$ gcc -Wall test3.cpp -lstdc++ -std=c++11 -o test3 test3.cpp:67:11: error: invalid explicit specialization before ‘>’ token template <> ^ test3.cpp:67:11: error: enclosing class templates are not explicitly specialized test3.cpp:68:46: error: invalid use of incomplete type ‘struct container<T>::template_iterator<container<T>::normal_iterator_type>’ void container<T>::iterator::individual_func() ^ test3.cpp:13:40: note: declaration of ‘struct container<T>::template_iterator<container<T>::normal_iterator_type>’ template <class iterator_type> struct template_iterator ^ test3.cpp:74:11: error: invalid explicit specialization before ‘>’ token template <> ^ test3.cpp:74:11: error: enclosing class templates are not explicitly specialized test3.cpp:75:51: error: invalid use of incomplete type ‘struct container<T>::template_iterator<container<T>::hoge_iterator_type>’ void container<T>::hoge_iterator::individual_func() ^ test3.cpp:13:40: note: declaration of ‘struct container<T>::template_iterator<container<T>::hoge_iterator_type>’ template <class iterator_type> struct template_iterator ^ test3.cpp:81:11: error: invalid explicit specialization before ‘>’ token template <> ^ test3.cpp:81:11: error: enclosing class templates are not explicitly specialized test3.cpp:82:55: error: invalid use of incomplete type ‘struct container<T>::template_iterator<container<T>::hogehoge_iterator_type>’ void container<T>::hogehoge_iterator::individual_func() ^ test3.cpp:13:40: note: declaration of ‘struct container<T>::template_iterator<container<T>::hogehoge_iterator_type>’ template <class iterator_type> struct template_iterator
初めは基点になるイテレータクラスを作って、そこから派生させたのですが、オーバーロードしなければならないかつ中身が親クラスのそれとほとんど同じような関数(=,+=,+等)がたくさんあり、派生させた意味があまりないような気がしたので、こちらの方法に変更したところです。
理想の実行結果はこんなかんじです。
template_iterator::shared_func() template_iterator::shared_func() template_iterator::shared_func() iterator::individual_func() hoge_iterator::individual_func() hogehoge_iterator::individual_func()
回答よろしくお願いします。
環境
gcc version 5.4.1 20160904 (Ubuntu 5.4.1-2ubuntu1~16.04)

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。