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;