指向函数的指针vs作为模板非类型形参的函数
Pointer to function vs function as template non-type parameter
我试图理解下面代码片段中发生了什么:
// using FUN = void(*)(void);
using FUN = void(void);
template<FUN fun> struct Fun{};
int main ()
{
FUN fun;
Fun<fun>{};
}
我可以使用void(void)
作为函数的非类型参数,一切正常,程序编译。但是,将类型更改为指向函数的指针,即删除第一行的注释并注释第二行,会导致错误
(g++)错误:'fun'的值不能用于常量表达式
(clang)错误:'FUN'类型的非类型模板参数(也称为'void (*)()')不是常量表达式
到底是怎么回事?函数类型实际上与指向函数的指针相同(即,无处不在地隐式转换?)我知道函数的指针不应该工作,因为FUN fun;
在main
它不是一个常量表达式,但为什么声明FUN
作为void(void);
使它工作?
将类型为"array of
T
"或"function returningT
"的非类型模板参数调整为type"指向T
的指针"或"指向返回T
的函数的指针"
([temp。(c++中的参数)
因此,模板Fun
是同一个模板,无论FUN
是声明为函数类型还是指向函数类型的指针。
但是,这个块声明:
FUN fun;
有不同的含义取决于FUN
是什么。如果FUN
是一个函数,则这是一个函数的块声明(如果使用odr,则必须在其他地方定义)。一般来说,可以使用函数名作为指向函数的指针类型的模板形参的实参——这里没有问题。但是如果FUN
是一个函数指针,这将创建一个未初始化的函数指针。因为它是一个非const
对象,所以它不能用作模板参数,就像int
变量不能用作int
模板参数的模板参数一样,但const int
变量可以。
相关文章:
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 关于 C++ 中的函数类型定义
- 用于检测函数类型是否为否的特征
- 函数类型参数的模板参数推导
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++无效的函数类型转换
- STL 函数和函数类型与函数指针类型
- 如何将result_of与函数类型定义一起使用
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- 专门用于"direct"函数类型(与函数指针类型相对)
- 将函数类型作为模板参数传递不会编译
- 通过参数传递 lambda(无函数类型模板)
- 如何在模板参数中分离函数类型返回类型和参数
- 为什么比较函数类型需要指定为模板参数?
- 带有限定符的函数类型定义用例
- 如何声明对函数类型的常量引用
- 非类型模板参数允许各种函数类型?