让函数指针模板参数接受右值引用是不是合法?
Posted
技术标签:
【中文标题】让函数指针模板参数接受右值引用是不是合法?【英文标题】:Is it legal to have a function pointer template parameter accept an rvalue reference?让函数指针模板参数接受右值引用是否合法? 【发布时间】:2014-10-29 13:39:14 【问题描述】:使用 Microsoft Visual Studio 2012,我尝试编译以下内容:
template <void (*f)(int && y)>
void foo()
并得到这个错误:
error C2993: 'int &&' : illegal type for non-type template parameter 'y'
这真的违法吗?或者这是 MSVS 中的错误?如果是这样,有谁知道它是否适用于更高版本?
【问题讨论】:
这里没有违法的。可能是 MSVC 被函数指针类型的第一个参数的名称y
混淆了,这里没有必要。试试template <void (*f)(int&&)>
。
对于 G++,您必须添加 -std=c++0x 作为编译器选项,否则它将无法解析。
jrok,你太棒了!删除“y”可以解决该错误。如果您将此作为官方答案发布,我会接受。
C++11 模式下的 GCC 也接受这一点,因此它很可能是一个 MSVC 错误。
【参考方案1】:
这确实是 VS2012 编译器中的一个拒绝有效错误,它被函数类型中的参数名称混淆,认为函数类型的参数是模板参数,因此投诉。 C++11 模式下的 G++ 4.8 和 4.9 接受此代码,Clang 3.3 和 ICC 13 也是如此;这是使用Godbolt's interactive compiler 检查的。此外,根据N3337 14.1 (temp.param) p4,对函数的指针和左值引用是允许的,不受函数参数或返回类型的限制:
非类型模板参数应具有以下之一(可选 cv-qualified) 类型:
整数或枚举类型, 指向对象的指针或指向函数的指针, 对对象的左值引用或对函数的左值引用, 指向成员的指针,std::nullptr_t
。
解决方法是 jrok 在 cmets 中提到的:只需从函数类型中删除参数名称——我能够测试的所有编译器都接受这个。
【讨论】:
以上是关于让函数指针模板参数接受右值引用是不是合法?的主要内容,如果未能解决你的问题,请参考以下文章