質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

4835閲覧

C++ - 子クラスのテンプレート引数を親クラスに渡す方法について

tiitoi

総合スコア21954

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/03/12 08:49

編集2019/03/12 08:55

環境

  • Visual Studio 2017
  • C++11

内容

下記のような親子関係があるテンプレートクラスを Curiously Recurring Template Pattern で作りました。

cpp

1#include <iostream> 2 3// 親クラス 4template <class Child> 5struct Base 6{ 7 void interface() 8 { 9 static_cast<Child *>(this)->implementation(); 10 } 11}; 12 13// 子クラス1 14struct Derived1 : Base<Derived1> 15{ 16 void implementation() 17 { 18 std::cout << "Derived1" << std::endl; 19 } 20}; 21 22// 子クラス2 23struct Derived2 : Base<Derived2> 24{ 25 void implementation() 26 { 27 std::cout << "Derived2" << std::endl; 28 } 29}; 30 31int main(int argc, char *argv[]) 32{ 33 Derived1().interface(); 34 Derived2().interface(); 35}

output

1Derived1 2Derived2

その後、親クラスに1つテンプレート引数を追加したくなりました。
そのため、子クラスにもテンプレート引数を追加して、親クラスにそのまま渡すようにしたところ、下記のようなコンパイルエラーが出ました。

cpp

1// 親クラス 2template <class Child, class SomeType> 3struct Base 4{ 5 void interface() 6 { 7 static_cast<Child *>(this)->implementation(); 8 } 9 10 protected: 11 SomeType hoge; 12}; 13 14// 子クラス1 15template <class SomeType> 16struct Derived1 : Base<Derived1, SomeType> // コンパイルエラーその1 17{ 18 void implementation() 19 { 20 std::cout << "Derived1" << std::endl; 21 } 22}; 23 24// 子クラス2 25template <class SomeType> 26struct Derived2 : Base<Derived2, SomeType> // コンパイルエラーその2 27{ 28 void implementation() 29 { 30 std::cout << "Derived2" << std::endl; 31 } 32}; 33 34int main(int argc, char *argv[]) 35{ 36 Derived1<int>().interface(); 37 Derived2<int>().interface(); 38}
エラー: C3203: 'Derived1': 非特殊 クラス テンプレート は、テンプレート 引数として テンプレート パラメーター 'Child' に使用できません。実際の型を指定してください コンパイル対象の クラス テンプレート インスタンス化 'Derived1<SomeType>' のリファレンスを確認してください エラー: C3203: 'Derived2': 非特殊 クラス テンプレート は、テンプレート 引数として テンプレート パラメーター 'Child' に使用できません。実際の型を指定してください コンパイル対象の クラス テンプレート インスタンス化 'Derived2<SomeType>' のリファレンスを確認してください

エラーIDで検索しても コンパイラ エラー C3203 | Microsoft Docs ぐらいしか情報がなく、参照してもなにが問題なのかわからないのですが、どなたかご教示いただけないでしょうか。

聞きたいこと

  • コンパイルエラーとなる理由
  • このような事はそもそも実現可能かどうか (代替案でもよいです)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

https://wandbox.org/permlink/uVyNmg1EKLUZXExx

継承のところで自身のクラスのtemplate実引数を書き忘れています。

cpp

1#include <iostream> 2// 親クラス 3template <class Child, class SomeType> 4struct Base 5{ 6 void interface() 7 { 8 static_cast<Child *>(this)->implementation(); 9 } 10 11 protected: 12 SomeType hoge; 13}; 14 15// 子クラス1 16template <class SomeType> 17struct Derived1 : Base<Derived1<SomeType>, SomeType> // Derived1<SomeType>に 18{ 19 void implementation() 20 { 21 std::cout << "Derived1" << std::endl; 22 } 23}; 24 25// 子クラス2 26template <class SomeType> 27struct Derived2 : Base<Derived2<SomeType>, SomeType> // Derived2<SomeType>に 28{ 29 void implementation() 30 { 31 std::cout << "Derived2" << std::endl; 32 } 33}; 34 35int main() 36{ 37 Derived1<int>().interface(); 38 Derived2<int>().interface(); 39}

投稿2019/03/12 09:14

編集2019/03/12 09:15
yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2019/03/12 09:20

なるほど。コンパイルエラーの原因はそういう事だったのですね。 迅速なご回答ありがとうございます!
yumetodo

2019/03/12 09:34

Visual Studio付属のcl.exeが出すtemplate周りのエラーメッセージは正直解読が難しいのでclangかgccでもコンパイルする習慣をつけるといいと思います。
yumetodo

2019/03/12 09:36

今回のもgccなら note: expected a type, got 'Derived1' と指摘してくれましたし clangなら error: use of class template 'Derived1' requires template arguments ともっと明確なメッセージを出してくれました。
tiitoi

2019/03/12 09:45

VC++ はとくにテンプレート関係のコンパイラエラーが参考にならないことが多くて困っていたのですが、他のコンパイラの出すエラーは問題点が的確にかかれていてよいですね。 VS は IDE としては使ってなかったので、コンパイラを切り替えようと思います。 情報ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問