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 - 你的工作是什么?,并寻求接受的答案 - 使用帮助程序类。

第二次尝试:

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

第三次尝试:

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 段错误(!)

为什么会发生这一切,我怎样才能让它发挥作用?

4

1 回答 1

2

修复错误后,您的第三次尝试应该有效;)

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在此限定名称之前放置一个。请参阅我必须在哪里以及为什么必须放置“模板”和“类型名称”关键字?

于 2013-11-14T18:28:19.420 回答