de-vraag
  • 質問
  • タグ
  • ユーザー
通知:
報酬:
登録
登録すると、質問に対する返答やコメントが通知されます。
ログイン
すでにアカウントをお持ちの方は、ログインして新しい通知を確認してください。
追加された質問、回答、コメントには報酬があります。
さらに
ソース
編集
 Martin
Martin
質問

"typename"キーワードはいつ必要ですか?

可能重複:
  正式にtypenameは何ですか?
  テンプレートをどこに置く必要があるのですか? typenameのキーワードは?

以下のコードを検討してください:

template
class C {
    struct P {};
    vector

vec; void f(); }; template void C::f() { typename vector

::iterator p = vec.begin(); }

この例で「typename」キーワードが必要な理由は何ですか? 「typename」を指定する必要がある場合は他にもありますか?



50 2011-10-27T22:53:54+00:00 3
 Community
Community
編集された質問 23日 5月 2017 в 12:10
プログラミング
c++
syntax
templates
typename
Kerrek SB
27日 10月 2011 в 11:00
2011-10-27T23:00:39+00:00
さらに
ソース
編集
#56793850

短い答え:名前が従属名のネストされた名前を参照するときはいつでも、パラメータが未知のテンプレートインスタンスの中に入れ子になっています。

長い答え:C ++には、値、型、テンプレートという3つのエンティティがあります。それらのすべてが名前を持つことができます。名前だけではエンティティのどの階層であるかは分かりません。むしろ、名前の実体の性質に関する情報は、文脈から推論されなければならない。

この推論が不可能なときはいつでも、それを指定する必要があります:

template  struct Magic;//defined somewhere else

template  struct A
{
  static const int value = Magic::gnarl;//assumed "value"

  typedef typename Magic::brugh my_type;//decreed "type"
 //     ^^^^^^^^

  void foo() {
    Magic::template kwpq(1, 'a', .5);//decreed "template"
   //       ^^^^^^^^
  }
};

Here the names Magic::gnarl, Magic::brugh and Magic::kwpq had to be expliciated, because it is impossible to tell: Since Magic is a template, the very nature of the type Magic depends on T -- there may be specializations which are entirely different from the primary template, for example.

What makes Magic::gnarl a dependent name is the fact that we're inside a template definition, where T is unknown. Had we used Magic, this would be different, since the compiler knows (you promise!) the full definition of Magic.

(これを自分でテストしたい場合は、使用できる Magic のサンプル定義を次に示します。簡潔にするためにspecializeで constexpr を使用してください。コンパイラは、静的メンバ定数の宣言を古いスタイルのpre-C ++ 11フォームに自由に変更することができます。)

template  struct Magic
{
  static const T                    gnarl;
  typedef T &                       brugh;
  template  static void kwpq(int, char, double) { T x; }
};
template <> struct Magic
{
 //note that `gnarl` is absent
  static constexpr long double brugh = 0.25; //`brugh` is now a value
  template  static int kwpq(int a, int b) { return a + b; }
};

使用法:

int main()
{
  A a;
  a.foo();

  return Magic::kwpq(2, 3); //no disambiguation here!
}
62
0
K-ballo
27日 10月 2011 в 10:56
2011-10-27T22:56:33+00:00
さらに
ソース
編集
#56793849

iterator は P の依存型なので、 typename キーワードが必要です。コンパイラは、 iterator が値または型を参照しているかどうかを推測することはできませんので、 typename テンプレートの引数に依存する型がある場合は常に、型または値が有効であるコンテキストで必要です。たとえば、基底クラスは型でなければならないので、基底クラス typename は不要です。

同じ主題では、 template というキーワードがあります。これは、依存名が値ではなくテンプレート関数であることをコンパイラに知らせるためです。

10
0
sehe
27日 10月 2011 в 10:56
2011-10-27T22:56:30+00:00
さらに
ソース
編集
#56793848

typenameキーワードは、型名がテンプレートパラメータに依存する場合に必要です(コンパイラは識別子の意味( type または value )最初のパスで完全なシンボルテーブル)。


Not in the same meaning, and a bit less common, the lone typename keyword can also be useful when using generic template parameters: http://ideone.com/amImX

#include 
#include 
#include 

template 
7
0
質問の追加
カテゴリ
すべて
技術情報
文化・レクリエーション
生活・芸術
科学
プロフェッショナル
事業内容
ユーザー
すべて
新しい
人気
1
Денис Анненский
登録済み 1日前
2
365
登録済み 5日前
3
True Image
登録済み 6日前
4
archana agarwal
登録済み 1週間前
5
Maxim Zhilyaev
登録済み 1週間前
ID
KO
RU
© de-vraag :年
ソース
stackoverflow.com
ライセンス cc by-sa 3.0 帰属