0

私はC ++ 03を使用しています(実際にはCUDA nvccですが、それは問題ではありません)。次の作業コードがあります。

template<typename T> void baz(T*);

template<typename T>
void bar() {
    typedef void (*foo_t)(T*);
    static const foo_t dummy = baz;
    // use dummy
};

ここで、ダミー変数を関数の外に移動して、グローバルにします。

最初の試み:

template<typename T> void baz(T*);
template<typename T> typedef void (*foo_t)(T*);
template<typename T> const foo_t dummy = baz;

template<typename T>
void bar() {
    // use dummy
};

C++ (少なくとも C++03) にはテンプレート化された typedef がないため、これは機能しません。

error: "typedef" may not be specified here

error: "foo_t" is not a function or static data member

C++03 にこれがないのはなぜですか? 私を殴る。関数内でできるのに、なぜ外でもできないのかわかりません。C++11もそうではないと思います(しかし、テンプレートusing化されたものがありますよね?)

わかりました、それで私はTemplate typedefs - What's your work around?を読みました。、そしてヘルパークラスを使用して、受け入れられた答えに行きました。

2 回目の試行:

template<typename T> void baz(T*);
template<typename T> class TemplatingHeler {
  typedef void (*foo_t)(T*);
  static const foo_t dummy = baz;
}

...これは次のようになります:

error: a member of type "void (*const)(T *)" cannot have an in-class initializer

3 回目の試行:

template<typename T> void baz(T*);
template<typename T> class TemplatingHelper {
  typedef void (*foo_t)(T*);
  static foo_t dummy;
};
template<typename T> TemplatingHelper::dummy = baz;

error: name followed by "::" must be a class or namespace name

error: argument list for class template "TemplatingHelper" is missing

...そして nvcc segfaults (!)

なぜこのようなことが起こるのでしょうか? どうすれば機能させることができるでしょうか?

4

1 に答える 1

2

エラーを修正した後、3回目の試行が機能するはずです;)

template<typename T> void baz(T*);
template<typename T> class TemplatingHelper {
  typedef void (*foo_t)(T*);
  static foo_t dummy;
};

template<typename T>                   // template-declaration
typename TemplatingHelper<T>::foo_t    // type
TemplatingHelper<T>::dummy             // name
= baz;                                 // initializer

冗長であることに同意しますが、宣言の一般的な形式に従います。

type name initializer ;

名前は既に宣言されており、クラス テンプレート内で型が指定されています。

この場合、それはテンプレート宣言であるため、そのtemplate<typename T>部分を追加する必要があります。部分的な特殊化も参照できるため、これは必須です。

template<typename T, typename U> class TemplatingHelper<T(*)(U)>
{
    typedef T(*foo_t)(U);
    static foo_t dummy;
};

template<typename T, typename U>
typename TemplatingHelper<T(*)(U)>::foo_t
TemplatingHelper<T(*)(U)>::dummy
= baz;

タイプは必須であり、宣言された名前の前にあるため、それを見つけるスコープを明示的に指定する必要があります。

TemplatingHelper<T>::foo_t

typename残念ながら、名前検索では、この修飾名の前に a を付ける必要があります。「template」および「typename」キーワードをどこに、なぜ入力しなければならないのですか? を参照してください。

于 2013-11-14T18:28:19.420 に答える