gcc 的显式实例化失败 - 为什么?
Explicit instantiation failing with gcc - why?
我有以下(简化的,因此很傻)代码:
template <typename Function, Function f, typename... Arguments>
void call_wrapper(Arguments... arguments)
{
f(arguments...);
}
然后:
void foo() { return; }
template void call_wrapper<decltype(foo), foo>();
void bar(int x) { return; }
template void call_wrapper<decltype(bar), bar, int>(int x);
当我用 clang 3.5.0 编译它时,它可以工作;但是如果我尝试用 gcc 4.9.3 或 5.1.1 编译它,我得到:
a.cpp:10:15: error: template-id ‘call_wrapper<void(), foo>’ for ‘void call_wrapper()’ does not match any template declaration
template void call_wrapper<decltype(foo), foo>();
^
a.cpp:13:15: error: template-id ‘call_wrapper<void(int), bar, int>’ for ‘void call_wrapper(int)’ does not match any template declaration
template void call_wrapper<decltype(bar), bar, int>(int x);
^
这是为什么?
注意:我对 C++11 的答案比 C++14/C++17 的答案更感兴趣,如果有任何区别的话。无论如何,这就是我调用 gcc 的方式。
decltype(fun)
的类型,其中 fun
是一个函数,嗯,函数的类型。尽管使用 fun
看起来非常像它应该具有相同的类型,但实际上并非如此:您不能拥有函数类型的对象,即 fun 的类型,当作为参数传递时,恰好是 decltype(fun)*
。如果您将指针滑入实例化(如 foo
所示)或在应用 decltype() (as shown for
bar` 之前显式衰减类型)它应该可以工作:
void foo() { return; }
template void call_wrapper<decltype(foo)*, foo>();
void bar(int x) { return; }
template void call_wrapper<decltype(+bar), bar, int>(int x);
我发现有一条关于 clang 实例化的评论。 clang 似乎错误地接受了原始代码。
我有以下(简化的,因此很傻)代码:
template <typename Function, Function f, typename... Arguments>
void call_wrapper(Arguments... arguments)
{
f(arguments...);
}
然后:
void foo() { return; }
template void call_wrapper<decltype(foo), foo>();
void bar(int x) { return; }
template void call_wrapper<decltype(bar), bar, int>(int x);
当我用 clang 3.5.0 编译它时,它可以工作;但是如果我尝试用 gcc 4.9.3 或 5.1.1 编译它,我得到:
a.cpp:10:15: error: template-id ‘call_wrapper<void(), foo>’ for ‘void call_wrapper()’ does not match any template declaration
template void call_wrapper<decltype(foo), foo>();
^
a.cpp:13:15: error: template-id ‘call_wrapper<void(int), bar, int>’ for ‘void call_wrapper(int)’ does not match any template declaration
template void call_wrapper<decltype(bar), bar, int>(int x);
^
这是为什么?
注意:我对 C++11 的答案比 C++14/C++17 的答案更感兴趣,如果有任何区别的话。无论如何,这就是我调用 gcc 的方式。
decltype(fun)
的类型,其中 fun
是一个函数,嗯,函数的类型。尽管使用 fun
看起来非常像它应该具有相同的类型,但实际上并非如此:您不能拥有函数类型的对象,即 fun 的类型,当作为参数传递时,恰好是 decltype(fun)*
。如果您将指针滑入实例化(如 foo
所示)或在应用 decltype() (as shown for
bar` 之前显式衰减类型)它应该可以工作:
void foo() { return; }
template void call_wrapper<decltype(foo)*, foo>();
void bar(int x) { return; }
template void call_wrapper<decltype(+bar), bar, int>(int x);
我发现有一条关于 clang 实例化的评论。 clang 似乎错误地接受了原始代码。