繁体   English   中英

非指针函数类型可以是非类型参数吗?

[英]Non-pointer function type can be a non-type parameter?

我一直在试验C ++中的函数类型。 请注意,我的意思不是指向函数的指针类型,例如:

typedef void (*voidFuncPtr)();

但更加奇特:

typedef void (voidFunc)();

我没想到会编译以下代码,但是令人惊讶的是:

template<voidFunc func>
class funcClass
{
public:
    void call() { func(); };
};

void func()
{ }

void Test()
{
    funcClass<func> foobar;
    foobar.call();
}

但是,如果我尝试将以下内容添加到funcClass:

voidFuncPtr get() { return &func; }

我收到错误Address expression must be an lvalue or a function designator

我的第一个问题是:编译器用来假装func类型实际上是可以传递给实例的东西? 只是把它当作参考? 第二个问题是:如果它甚至可以被调用,为什么不能使用它的地址? 另外,这些非指针功能类型称为什么? 我只是因为boost :: function而发现了它们,却从未找到关于它们的任何文档。

该标准的第14.1.4节规定:

非类型模板参数应具有以下(可选,具有cv限定)类型之一:

—整数或枚举类型,

—指向对象的指针指向函数的指针 ,[ 这就是你的 ]

—对对象的左值引用或对函数的左值引用,

—指向成员的指针,

— std :: nullptr_t。

§14.1.6说

非类型非参考模板参数是prvalue。 不得将其赋值或以任何其他方式更改其值。 非类型非引用模板参数不能采用其地址 当非类型非引用模板参数用作引用的初始化程序时,始终使用临时变量。

这样就可以解释您所看到的两种行为。

请注意, func&func (§14.3.2.1)相同:

[非类型模板参数可以是]一个常数表达式(5.19),该常数指定具有静态存储期限和外部或内部链接的对象的地址,或者具有外部或内部链接的函数,包括函数模板和函数模板ID,但不包括非静态类成员,表示为&id-expression(忽略括号),但如果名称是指函数或数组 ,则可以省略&;如果相应的template-parameter是引用,则应省略; 要么...

因此,它只是一个函数指针。

假定代码编译时没有地址操作符和指针(包括函数和成员函数的指针)是有效的模板参数,似乎编译器认为voidFunc是函数指针类型,即该类型的衰减版本。 在C ++ 2003和C ++ 2011之间,此规则不变。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM