3

テンプレート引数がコンパイル時に評価されることは、他の Stackoverflow スレッド (このような) の束から理解しています。また、非型の template-parameter は、定数式、整数式、または外部リンケージを持つオブジェクトへのポインターのいずれかである必要があります。

また、Makefile の g++ コマンドで --std=c++0x を使用していません。

では、引数として渡された NULL を使用してテンプレート クラスをインスタンス化することは可能ですか?

// I have a template class like this - 
template<class T, T invalidVal, int e> class A
{ 
    static inline bool dummy(T value) 
    {
       return 0;
    }
}

#define MY_INVALID_VAL ((void *)0)

// Now I want create class from the above template class with 
// T=void*, invalidVal=NULL & e=0 
typedef A<void *, MY_INVALID_VAL, 1> ClassA;

上記のコードは、MS Visual Studio 2008 で正常にコンパイルされます。g++ では、エラーが発生します。

グーグルで調べた後、いくつかのオプションを試しました-

「extern void *MY_INVALID_VAL;」を宣言します。ヘッダー ファイルに - インクルードして void MY_INVALID_VAL=NULL;を実行します。テンプレートのインスタンス化の前。その場合、 「定数ポインターではないため、MY_INVALID_VAL は型 'void' の有効なテンプレート引数ではありません」というエラーが表示されます。

だから私の質問は - c++0x 標準を使用せずに NULL 引数でテンプレート クラスをインスタンス化する方法はありませんか?

ありがとう!

編集:

すべてのコメントに感謝し、標準のドラフトから正確なセクションを引用してくれてありがとう。

私が試したことをリストアップするだけです-

1) 「0」を直接渡すと機能しません。私が得るエラーは - 「'0' をテンプレート引数 void * に変換できませんでした」です。

2) static const void *my_null=0; の宣言 my_null を渡すと機能しません。エラーが発生しました-「my_nullは定数式に表示できません」

3)コメントの1つで提案されているnullオブジェクトへのポインター(nullオブジェクトパターン)アプローチを試しました以下を参照してください-

class my_null
{
 public:
     my_null() { my_null_ptr = NULL; }
     void * get() { return my_null_ptr; }
 private:
    void *my_null_ptr;
};
my_null my_null_obj;
my_null *ptr = &my_null_obj;

typedef A<void *, (void *)ptr, 1> ClassA;

それでもエラーが発生します-「ptr can not appear in constant expression」

だから今、これは疑問に思っています-それを機能させるにはどの値を渡す必要がありますか? または、それを機能させることはできませんか?(c++11 std を使用しない方法を意味します) コンパイルを成功させる値をまだ見つけていません。

どんな助けも感謝します(そして必要です:-P)!

補足として、もう 1 つ質問したいのは、非型のテンプレート引数に使用できるポインター値はありますか?

4

2 に答える 2

6

C++98 では、非型テンプレート引数は次のいずれかでなければならないと言われています

  • 整数型または列挙型の整数定数式。また
  • 非型のtemplate-parameterの名前。また
  • id-expressionとして表される、関数テンプレートおよび関数テンプレート IDを含むが、非静的クラス メンバーを除く、外部リンケージを持つオブジェクトまたは関数の名前。また
  • 関数テンプレートと関数テンプレート IDを含むが非静的クラス メンバーを除く、外部リンケージを持つオブジェクトまたは関数のアドレス。名前が関数または配列を参照する場合、& はオプションです。また
  • 5.3.1 で説明されているように表現されたメンバーへのポインター。

null ポインターはこのリストのどの項目にも該当しないため、null ポインターを非型のテンプレート パラメーターとして渡すことは無効です。

C++11 は、このリストを次のように更新します

  • 整数型または列挙型の非型テンプレート パラメーターの場合、テンプレートパラメーターの型の変換された定数式 (5.19) 。また
  • 非型のtemplate-parameterの名前。また
  • 関数テンプレートと関数テンプレート IDを含むが非静的クラス メンバーを除く、静的ストレージ期間と外部または内部リンケージを持つオブジェクト、または外部または内部リンケージを持つ関数のアドレスを指定する定数式 (5.19)ただし、名前が関数または配列を参照する場合は&を省略でき、対応するtemplate-parameterが参照の場合は省略しなければなりません。また
  • null ポインター値に評価される定数式 (4.10)。また
  • null メンバ ポインタ値に評価される定数式 (4.11)。また
  • 5.3.1 で説明されているように表現されたメンバーへのポインター。

更新された要件は、null ポインターをカバーしています。したがって、null ポインターを非型テンプレート引数として使用するには、C++11 を使用する必要があります。

于 2012-09-28T03:01:44.470 に答える
1

これを試して:

static const void* my_null_pointer = 0;
typedef A<void *, my_null_pointer, 1> ClassA;

そのようなものは、MSVC と gcc でも機能しました。そのテンプレート パラメータとして 0 を渡すことも同様に機能するはずです。

typedef A<void *, 0, 1> ClassA;
于 2012-09-28T02:49:05.927 に答える