2

次のコードを検討してください。

template < class A >
class XX {
  public:
  template <int (*CC)() >
  int bla (){ return CC(); }
  int stam() {return 0;}
  int f() {
    return bla<stam>();
  }
};

int main()
{ 
  XX<int> xx;
  printf(" this is %d\n", xx.f());
  return 0;
}

失敗する

test.cpp: In member function ‘int XX<A>::f() [with A = int]’:
test.cpp:14:   instantiated from here
test.cpp:8: error: ‘int XX<A>::stam() [with A = int]’ cannot appear in a constant-expression**

考えてみれば明らかです。stamテンプレートがインスタンス化されるまで存在しないため、関数アドレスはありません。テンプレートがインスタンス化されると、インスタンスはコードのどこかで分解されstam、アドレスが取得されます。したがって、アドレスはコンパイル時に一定ではありません (作業によってはそうなる可能性もありますが、これはサポートされていません)。

では、なぜ私はこれをやろうとしているのでしょうか。関数ポインターまたは仮想関数を使用できます。実際blaには、それを使用するstam(stam1とが存在するstam2) ことは無数の回数と呼ばれ、マイナーなパフォーマンスの改善 (間接参照を使用しないなど) でさえ歓迎されます。

もちろん解決策はあります: Createbla1bla2which はほぼ同じです。プリプロセッサ マクロを記述します。エレガントな解決策があるかどうか疑問に思っています。

4

2 に答える 2

3

これは正常にコンパイルされます:

#include <cstdio>
using namespace std;

template < class A >
class XX {
  public:
  template <int (XX<A>::*CC)()>
  int bla (){ return (this->*CC)(); }
  int stam() {return 0;}
  int f() {
    return bla<&XX<A>::stam>();
  }
};

int main()
{.
  XX<int> xx;
  printf(" this is %d\n", xx.f());
  return 0;
}

修正は、メソッドへのポインター テンプレート パラメーターの正しい署名と、メソッド ポインターを指定するための正しい構文を使用することです。(実際には、そこを省略できます<A>。)

于 2012-10-22T23:28:14.340 に答える
0

問題は、stam() がフリー関数ではなくメンバー関数であるため、"this" ポインターを使用して呼び出す必要があることです。

メンバー関数へのポインターに関するこのチュートリアルを読んでください。

http://www.parashift.com/c++-faq/pointers-to-members.html

于 2012-10-22T23:11:27.407 に答える