定义外联成员模板函数
Defining out-of-line member template functions
考虑这个(最小化的)示例:
template <typename Descriptor>
class hash_table
{
public:
typedef int value_type;
template <typename Argument, int Callback (value_type *, Argument)>
void traverse (Argument);
template <int Callback (value_type *)>
void traverse_void ();
};
我定义了一个 class 模板,其中包含带有非类型参数的模板成员函数。请注意 Callback
取决于 value_type
typedef。现在我想自己定义函数:
template <typename Descriptor>
template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)>
void hash_table <Descriptor>::traverse (Argument) {}
template <typename Descriptor>
template <int Callback (typename hash_table <Descriptor>::value_type *)>
void hash_table <Descriptor>::traverse_void () {}
我从编译器中得到不一致的错误。结果不依赖于选项,指定 C++ 标准的版本(即,与 C++98、C++11 和 C++14 相同),但取决于编译器。
GCC 6.0.0(最近的主干,以及其他几个版本)接受此代码。
Clang 3.7.0(最近的主干)给出以下错误:
test.cc:18:31: error: out-of-line definition of 'traverse_void' does not match any declaration in 'hash_table<Descriptor>'
void hash_table <Descriptor>::traverse_void() {}
^~~~~~~~~~~~~
1 error generated.
EDG(英特尔 C++ 编译器 v.15.0.3)给出了两个错误:
test.cc(15): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse<Argument,Callback>(Argument)" (declared at line 7)
void hash_table <Descriptor>::traverse (Argument) {}
^
test.cc(19): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse_void<Callback>()" (declared at line 10)
void hash_table <Descriptor>::traverse_void () {}
^
compilation aborted for test.cc (code 2)
预期的行为是什么(根据标准)?如果代码错误,我该如何修改函数定义?
我觉得你的代码很好,我看不出有什么理由不编译。可能是不允许它的编译器上的错误。但是,由于 [temp.param]:
A non-type template-parameter of type “array of T
” or “function returning T
” is adjusted to be of type
“pointer to T
” or “pointer to function returning T
”, respectively.
您可以简单地将 Callback
自己切换为指向函数的指针。行为在所有方面都是相同的,额外的好处是这段代码也可以在 clang 上编译。
考虑这个(最小化的)示例:
template <typename Descriptor>
class hash_table
{
public:
typedef int value_type;
template <typename Argument, int Callback (value_type *, Argument)>
void traverse (Argument);
template <int Callback (value_type *)>
void traverse_void ();
};
我定义了一个 class 模板,其中包含带有非类型参数的模板成员函数。请注意 Callback
取决于 value_type
typedef。现在我想自己定义函数:
template <typename Descriptor>
template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)>
void hash_table <Descriptor>::traverse (Argument) {}
template <typename Descriptor>
template <int Callback (typename hash_table <Descriptor>::value_type *)>
void hash_table <Descriptor>::traverse_void () {}
我从编译器中得到不一致的错误。结果不依赖于选项,指定 C++ 标准的版本(即,与 C++98、C++11 和 C++14 相同),但取决于编译器。
GCC 6.0.0(最近的主干,以及其他几个版本)接受此代码。
Clang 3.7.0(最近的主干)给出以下错误:
test.cc:18:31: error: out-of-line definition of 'traverse_void' does not match any declaration in 'hash_table<Descriptor>'
void hash_table <Descriptor>::traverse_void() {}
^~~~~~~~~~~~~
1 error generated.
EDG(英特尔 C++ 编译器 v.15.0.3)给出了两个错误:
test.cc(15): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse<Argument,Callback>(Argument)" (declared at line 7)
void hash_table <Descriptor>::traverse (Argument) {}
^
test.cc(19): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse_void<Callback>()" (declared at line 10)
void hash_table <Descriptor>::traverse_void () {}
^
compilation aborted for test.cc (code 2)
预期的行为是什么(根据标准)?如果代码错误,我该如何修改函数定义?
我觉得你的代码很好,我看不出有什么理由不编译。可能是不允许它的编译器上的错误。但是,由于 [temp.param]:
A non-type template-parameter of type “array of
T
” or “function returningT
” is adjusted to be of type “pointer toT
” or “pointer to function returningT
”, respectively.
您可以简单地将 Callback
自己切换为指向函数的指针。行为在所有方面都是相同的,额外的好处是这段代码也可以在 clang 上编译。