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

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

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

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

Q&A

解決済

2回答

2278閲覧

クラステンプレート内で型名を指定しなくていい理由

saki_chan

総合スコア40

C++

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

4グッド

4クリップ

投稿2019/07/30 19:55

編集2019/07/31 07:00

クラステンプレート内で、型名を指定しなくても使えてしまうのですが、これはどういった仕様でしょうか。
できれば、どうしてこのような仕様なのかも教えてくださると助かります。

C++

1template <typename T> 2struct X 3{ 4 //戻り値に<T>をつけなくて大丈夫なのはなぜ? 5 X f() 6 { 7 return *this; 8 } 9}; 10 11int main() 12{ 13 [[maybe_unused]] X<int> x; 14 [[maybe_unused]] X<int> x2 = x.f(); 15 16 return 0; 17}
yumetodo, yohhoy, Sateba👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

いまいち確信が持てませんがここかな・・・

C++11(N3337)より

[class] 2
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name. A class-specifier is commonly referred to as a class definition. A class is considered defined after the closing brace of its class-specifier has been seen even though its member functions are in general not yet defined. The optional attribute-specifier-seq appertains to the class; the attributes in the attribute-specifier-seq are thereafter considered attributes of the class whenever it is named.

[temp.local] 1
Like normal (non-template) classes, class templates have an injected-class-name (Clause [class]). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

つまりinjected-class-nameになるから使える理論。

投稿2019/08/01 01:06

編集2019/08/01 01:09
yumetodo

総合スコア5850

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

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

alphya

2019/08/01 04:43

yumetodo さんの回答の補足です! そして、injected-class-name になるので、https://ja.cppreference.com/w/cpp/language/dependent_name の「現在の実体化」より、「クラステンプレートの定義内で、そのテンプレートの注入されたクラス名(injected-class-name)」に該当するため、名前(ここでは X)は現在の実体化を参照すると推定され、テンプレート引数を省略できているようでした。 この記述の場所です。 C++11(N3337) [temp.dep.type]/1.1 https://timsong-cpp.github.io/cppwp/n3337/temp.dep.type#1.1
yumetodo

2019/08/01 04:46

あやや、読んでたのに引っ張り忘れてた、ありがとうございます。
alphya

2019/08/01 04:50

いえいえ、こちらこそ勉強になりました!ありがとうございます!
yohhoy

2019/08/01 15:11

補足: > どうしてこのような仕様なのかも教えてくださると助かります。 単純に「その方が便利だから」でしょうね。この仕様がなければ、クラステンプレート定義が恐ろしく煩雑になってしまいますから。 この仕様はC++初期から存在するようです。(C++98→03で若干文面は変わったらしい) https://stackoverflow.com/questions/25549652/
takabosoft

2019/08/02 08:49 編集

私は時間稼ぎにしかなりませんでしたが(?)ありがとうございました!
guest

0

//戻り値に<T>をつけなくて大丈夫なのはなぜ?

構文的には間違っていないからではないでしょうか?
戻り値の型がstruct Xの関数fなだけですよね。

「T」をテンプレートの型として定義はしていますが、
絶対に使わないといけないという縛りは無いのかなと思います。

投稿2019/07/31 00:45

takabosoft

総合スコア8356

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

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

yumetodo

2019/07/31 02:01

質問の意図はtemplate classにおいて、自身のクラス型について型パラメータを省略できるのはどこで許可されているのか?ということだと思います・・・。 ほかにも template<typename T> struct X{ // copy ctor X(const X&);//引数はconst X<T>&じゃなくてよい // ctor template<typename T2> X(const X<T2>&);//const X<T>&以外(別のT)を受け取る }; など。
takabosoft

2019/07/31 02:17

んーでは、T型を使う前提のX型であればわざわざX<T>と書かなくて良い、というのが回答になりますかね。 C++の規格書のどこそこに、こう書かれているから、という1次ソースはもう少しC++のお強い方におまかせします。
saki_chan

2019/07/31 06:59

そうですね、どこで<T>を省略できるかが書かれているのかを知りたいです。 できれば、明確な理由等も教えてくださると助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問