下面的代码被VC++ 2012拒绝,并显示“错误C2207:“A::bar”:类模板的成员无法获取函数类型“”。
int Hello(int n)
{
return n;
}
template<class FunctionPtr>
struct A
{
A(FunctionPtr foo)
: bar(foo)
{}
FunctionPtr bar;
};
int main()
{
A<decltype(Hello)> a(Hello);
return 0;
}
为什么?
4条答案
按热度按时间gjmwrych1#
gcc对这个错误更友好一点:
最简单的解决方案是将
bar
声明为函数指针:在这种情况下,
decltype(Hello)
计算为int(int)
而不是int(*)(int)
。byqmnocz2#
变量不能有函数类型。声明
bar
为FunctionPtr
,即decltype(Hello)
,计算结果为int (int)
,而不是函数指针类型。这是令人困惑的,因为从C继承了一些不一致的地方。当您将
A
的构造函数定义为接受一个FunctionPtr
时,您可能会想到您会得到相同的错误。然而,声明为具有数组或函数类型的函数参数自动(不幸的是,不方便)转换为指针类型。因此,即使foo
被声明为具有函数类型,但它实际上具有函数指针类型并且工作正常。但是这个规则只适用于函数参数,而不适用于其他变量,所以
bar
实际上确实有一个函数类型,这是不法律的的。toe950273#
加上其他答案,您可以利用以下事实:
decltype(Hello)
计算为int (int)
(不是函数指针类型);下面的代码:
是一个通用的解决方案,允许对函数、函数指针、函子和lambda表达式使用相同的语法:
(here我利用C++14的特性稍微改变了解决方案)。
事实上,
std::function
是一个(并不总是更好的)替代方案。qxsslcnc4#
今天刚刚遇到这个-如果你用
decltype((Hello))
运行它应该没问题,而不必更改代码。详情见Scott Meyers