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

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

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

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

Q&A

解決済

2回答

617閲覧

CRTPにおける承継クラスの型の参照について

jbe00214

総合スコア63

C++

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

0グッド

1クリップ

投稿2021/06/23 06:54

前提・実現したいこと

いわゆるCRTPを使って静的ポリモフィッククラスを実装しようと思っています。しかし,承継したクラスの型を基本クラスから参照ができません。Webの記事でもそこまで踏み込んだ解説がありませんでした。おわかりになる方がおられれば,対処の仕方をご教示願えますでしょうか。

発生している問題・エラーメッセージ

//No type named 'type' in 'Foo<int>'

該当のソースコード

C++

1template <typename Derived> 2struct base 3{ 4 using type =typename Derived::type;//No type named 'type' in 'Foo<int>' 5 void f(type v) { 6 static_cast<Derived*>(this)->impl(v); 7 } 8}; 9 10 11template<typename T> 12struct Foo: public base<Foo<T>>{ 13 using type = T; 14 void impl(T v){cout << "Foo: " << v <<'\n';} 15}; 16 17int main(){ 18 Foo<int> foo; 19 foo.f(10); 20} 21

参考にしたこと

スタラウストラップのC++ 4版 p771を参考にしました。

C++

1template<typename N> 2struct Node_base : N::balance_type{ 3}; 4template<typename Val,typename Balance> 5struct Search_node 6 :public Node_base<Search_node<Val,Balance>> 7{ 8 using balance_type = Balance; 9};

補足情報(FW/ツールのバージョンなど)

clang
c++17

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

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

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

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

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

yumetodo

2021/06/23 14:08

そもそももとのコードからして私の手元ではコンパイルが通らないのですが何が悪いんだろう・・・ Baseクラスの引数増やせばかんたんではあるんですが多分望んでいるものではないですよねぇ。
jbe00214

2021/06/23 20:00 編集

そうなんです。ストラストラップの本に掲載されているコードもコンパイル出来ないのです。コンパイラの問題なのかとも思ったのですが。。。 エラーメッセージを見ると「foo<int>内に」とあるから,実体化もされているようです。根本の解決ではないですが,引数を増やしてできるのであればそれでも良いです。
yumetodo

2021/06/24 02:44

SaitoAtsushiさんの回答が私の言いたかったことですね・・・
guest

回答2

0

参考にしたコードというのが上手くいかないのは Search_node<Val,Balance> を実体化しようとする途中で (Node_base に渡すために) Search_node<Val,Balance> が必要になる構造だからですね。 Node_base が実体化されないと Search_node は実体化できないのに Search_node が実体化できないと Node_base が実体化できないというデッドロックが生じています。

メンバを経由しないようにすれば (型引数で渡せば) コンパイルを通るようになります。

cpp

1template<typename N, typename Balance> 2struct Node_base : public Balance { 3}; 4template<typename Val, typename Balance> 5struct Search_node 6 :public Node_base<Search_node<Val,Balance>, Balance> 7{ 8 // using balance_type = Balance; 9};

質問者が書いたコードで No type named 'type' in 'Foo<int>' というエラーが出るのも DerivedFoo<int> であることがわかっていてもまだそれの実体化は終わっていないというという状況だからです。

GCC だとエラーメッセージは invalid use of incomplete type 'struct Foo<int>' となるのでもう少し状況がわかりやすいですね。 (この時点では) Foo<int> は不完全型なのです。

投稿2021/06/24 01:31

SaitoAtsushi

総合スコア5684

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

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

jbe00214

2021/06/24 01:58

ありがとうございます。参考コードはコンパイルできるようになりました。そこで,元の問題の解決には,ベースクラスに doubleなどをどのように渡すのかですね。少し進展しました。
guest

0

自己解決

お陰様で次のコードで解決しました。ありがとうございました。

C++

1template<typename T> 2struct types{using type=T;}; 3 4template <typename Derived,typename types> 5struct base :public types 6{ 7 using type = typename types::type; 8 void f(type v) { 9 static_cast<Derived*>(this)->impl(v); 10 } 11}; 12 13 14template<typename T> 15struct Foo: public base<Foo<T>,types<T>>{ 16 17 void impl(T v){cout << "Foo: " << v <<'\n';} 18};

投稿2021/06/24 03:39

jbe00214

総合スコア63

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問