2

C++ 標準に従って、関数パラメーターの名前は declarator-id によって解析され、declarator -id修飾名にすることもできます。つまり、次のコードは完全に有効です (標準の関連セクションを正しく理解していれば)。

template<class T>
struct Sample
{
    int fun(int T::count); //T::count is qualified variable name
};

私の質問は基本的に、なぜそのようなコードを書くのでしょうか? どのような状況で、(関数のパラメーター リストで) 修飾名を使用すると有利になる可能性がありますか?


編集:

セクションを間違って理解したようです。上記のコードの代わりに、おそらく次のコードを書くことができます (C++ 標準に従って):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4はそれを完全にコンパイルします。しかし、私は完全に満足していません.T::countはもはやパラメータではありません.

4

3 に答える 3

2

無効です。構文は任意の宣言子を許可しますが、8.3.5p8 は言う

オプションで、識別子をパラメータ名として指定できます。関数定義 (8.4) に存在する場合、パラメーターに名前を付けます (「仮引数」と呼ばれることもあります)。

構文的に宣言子を制約する別の引用を編集(8.3p1、[dcl.meaning]):

各宣言子には、declarator-id が 1 つだけ含まれます。宣言されている識別子に名前を付けます。declarator-id の id-expression は、いくつかの特殊関数 (12.3、12.4、13.5) の宣言と、テンプレートの特殊化または部分的な特殊化 (14.7) の宣言を除いて、単純な識別子でなければなりません。宣言子 ID は、クラス外のメンバー関数 (9.3) または静的データ メンバー (9.4) またはネストされたクラス (9.7) の定義、関数、変数、またはクラス メンバーの定義または明示的なインスタンス化を除いて修飾されません。その名前空間の外側の名前空間の、またはその名前空間の外側で以前に宣言された明示的な特殊化の定義、または別のクラスまたは名前空間 (11.4) のメンバーであるフレンド関数の宣言。

したがって、パラメーター宣言では、修飾名を使用してはなりません。

編集: 編集された形式では、実際に存在し、整数定数であるint*かどうかのテストが行​​われる前であっても、関数パラメーターの型は に減衰します。T::countそのような署名の修飾名が意味のあることをする例が必要な場合は、

template<class T>
struct sample
{
  void fun(int S=T::count);
};

パラメータなしで gets が呼び出されるとfun、コンパイラはデフォルトの引数を決定する必要があります。これTは、countメンバーがない場合、または に変換できない場合に失敗しintます。

于 2010-12-11T14:57:13.943 に答える
1

私が理解している限り、あなたのコードは不正な形式です。

$ 8.3 / 1:declarator-idが修飾されている場合、宣言は、修飾子が参照するクラスまたは名前空間の以前に宣言されたメンバーを参照するものとし、そのメンバーは、スコープ内のusing-declarationによって導入されていないものとします。 declarator-idのnested-name-specifierによって指定されたクラスまたは名前空間。[注:修飾子がグローバル::スコープ解決演算子の場合、declarator-idはグローバル名前空間スコープで宣言された名前を参照します。]

PS:私は100%確信していません。私が間違っている場合は訂正してください。:)


どのような状況で、(関数パラメーターリストで)修飾名を使用すると有利な場合がありますか?

HerbSutterによるExceptionalC++のアイテム31と32を読んでください。どちらの項目も、ケーニッヒルックアップとインターフェイスの原則を扱っています。

于 2010-12-11T15:33:12.013 に答える
0

セクションを間違って理解したようです。そのコードの代わりに、おそらく次のコードを書くことができます (C++ 標準に従って):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 はそれを完全にコンパイルします。しかし、私は完全に満足していません。もうパラメーターT::countではないからです (私は推測します)。

于 2010-12-11T15:43:44.933 に答える