C++ decltype、result\u of或typeof?
我有: 以及:C++ decltype、result\u of或typeof?,c++,c++11,type-inference,C++,C++11,Type Inference,我有: 以及: 模板 Ev类{ 公众: (T::toCPD())D的typedef结果_; 实例化Ev后,编译器说: meta.h:12:错误:“T::toCPD”不是一个类型 decltype和typeof work都不是。的result\u既不是函数也不是运算符。的result\u是元函数,其函数为模板参数,并在成员类型上设置结果类型 template<typename T> class Ev { public: typedef result_of(T::toCPD()
模板
Ev类{
公众:
(T::toCPD())D的typedef结果_;
实例化Ev
后,编译器说:
meta.h:12:错误:“T::toCPD”不是一个类型
decltype和typeof work都不是。的result\u既不是函数也不是运算符。的result\u是元函数,其函数为模板参数,并在成员类型上设置结果类型
template<typename T>
class Ev {
public:
typedef result_of(T::toCPD()) D;
typedef typename结果_of::type D;
由于获得的任何结果都取决于模板参数,typedef typename
是必需的
decltype
是C++11的标准功能。它是一个“运算符”,接受表达式并返回类型
typedef typename result_of<T::toCPD()>::type D;
如果T()
不是有效的(T
不可默认构造),您将需要declval
,这是一个接受类型并返回该类型的无意义无效值的函数。declval
只能在未计算的上下文中使用,例如decltype
typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic
但是,这是非常脆弱的,因为如果出现任何重载(例如非常量版本),则无法解决
&T::toCPD
。这是正确的,尽管T*
或T const*
必须显式写出!在大多数情况下,您最好使用decltype
和declval
这是不可能的r在模板参数内调用函数是有效的。不过,decltype看起来应该可以工作。当然,除非OP的编译器不支持它。@jalf:decltype
的结果头是什么?@jalf:decltype
不工作,因为他试图使用:
调用一个非静态函数。请参见我的答案。@Potatoswatter:ah right,guess我应该正确地阅读代码。;)没有特殊的成员函数类型。成员函数的类型是普通函数类型。例如,成员函数指针是指向普通函数类型的成员指针:identity::type a::*
相当于void(a::*)()
。您不能将成员指针类型传递给的result\u。特别是,result\u of::type
被指定为decltype(declval()(declval())
,其中Fn
是传递的函数类型/函数对象类型或对它的引用。GCC有时会输出“type”void(T:)()类T
中类型为void()
的函数的
或类似类型。但这样的类型不存在-它只是冒泡出现的实现细节。实际上,仔细观察后,它更像result\u if
。因此,Fn
不能是函数类型(类型id将指定返回函数的函数).Fn
必须是对函数的引用或函数对象的引用或直接类型。和Args
调用它的参数。@litb:谢谢!很难弄清楚的结果\u应该做什么,因为我找不到GCC 4.5的单一工作案例。应该可以删除指针吗从一个ptmf类型获得一个函数类型?如果不是,那不是库中的一个漏洞吗?实现起来很容易!我似乎找不到现成的标准模板。作为一种解决方法,你可以做typedef typename result\u of::type
,我认为,但我认为这很难看:)出于一般兴趣,值得注意的是C++0x不允许对于非静态数据成员也是如此。例如,GCC4.5中已经有了struct A{int A;};decltype(A::A*3)b=0;
。对于非静态数据成员,只要它发生在C++0x中的未赋值操作数中,就可以执行任何操作。
typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic
typedef typename decltype( std::declval<T>().toCPD() ) D;
typedef typename std::result_of< decltype( & T::toCPD ) ( T * ) >::type D;