C++模板在传递函数签名时未进行编译
C++ template not compiling when passing through function signature
考虑以下最小示例(在没有#1
和#2
的情况下编译):
void foo(void)
{ }
template<typename T> class Stage2;
template<typename Ret, typename... Args>
struct Stage2<Ret (Args...)>
{
template<Ret (*func)(Args...)>
static void foobar(void)
{ /* Do something */ }
};
template<typename FuncType>
struct Stage1
{
template<FuncType func>
static void bar(void)
{
Stage2<FuncType>::foobar<func>(); // #1, Not working
Stage2<decltype(func)>::foobar<func>(); // #2, Not working
Stage2<void()>::foobar<func>(); // #3, Working
}
};
int main(void)
{
Stage1<decltype(foo)>::bar<foo>();
return 0;
}
为什么它不使用#1
和#2
编译,而使用#3
编译得很好?在我看来,只要foo有签名void()
,#3
就应该与其他的等价,在本例中就是这样。甚至编译器告诉我,FuncType
实际上就是void()
(见下文)。
错误消息(与#1
和#2
相同):
main.cpp: In static member function ‘static void Stage1<FuncType>::bar()’:
main.cpp:21:40: error: expected primary-expression before ‘)’ token
Stage2<FuncType>::foobar<func>(); // #1, Not working
^
main.cpp: In instantiation of ‘static void Stage1<FuncType>::bar() [with FuncType func = foo; FuncType = void()]’:
main.cpp:29:37: required from here
main.cpp:21:33: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘void (*)()’ to binary ‘operator<’
Stage2<FuncType>::foobar<func>(); // #1, Not working
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
我在这里错过了什么?我使用g++7.2.0。
注意:如果这在任何方面有用,我真的不感兴趣,我只想知道为什么它没有编译,因为它对我来说毫无意义
基本上,发生的是:
Stage2<FuncType>::foobar<func>();
包含一个依赖名称(取决于FuncType),因此您必须遵循正确的C++语法来调用成员模板(因此会出现语法错误消息),即
Stage2<FuncType>::template foobar<func>();
请注意,这不适用于Stage2<void()>::foobar<func>();
,因为不涉及从属名称。
这同样适用于Stage2<decltype(func)>::foobar<func>();
,但单凭这一点仍然无法解决问题,因为存在一些棘手的障碍。根据§14.1.8[温度参数],
类型为"T的数组"或"返回T的函数"的非类型模板参数被分别调整为类型为"指向T的指针"或"指向返回T的功能的指针"。
decltype(func)
将是void(*)()
而不是void()
(即使FuncType
被指定为void()
),因此没有函数类型,而是指向函数类型的指针将作为模板参数传递给没有提供专门化的Stage2
(因为Stage2<Ret (Args...)>
和Stage2<Ret (*)(Args...)>
不相同),从而返回到默认的模板声明,最后产生了"使用不完整类型"错误。
相关文章:
- 在运行时解析函数,而不是在编译C++解析函数
- 内联扩展编译为函数调用 [C++]
- 通过键入的引用问题传递函数
- 通过两个嵌套函数传递C++函数的名称
- C++中的编译时函数是什么?
- 如何从模板类传递函数
- 在 Linux 上编译 - 在函数 '_start' 中:(.text+0x20):对 'main' 的未定义引用
- 编译时函数的选择取决于类型大小
- C++模板-基于参数编译成员函数
- 为什么引用不能与编译时函数一起使用?
- 从私有函数传递函数作为参数
- 如何通过模板传递函数?
- 我可以在C++中部分编译模板函数吗?
- 传递函数指针时未解析的外部符号
- 传递函数指针代替插槽函数
- 如何在 arduino 中传递函数参数
- 编译模板函数时形式参数列表不匹配
- "double(*)(string, double, double)"尝试传递函数C++时"double"转换错误
- 按引用传递函数参数
- C++模板在传递函数签名时未进行编译