首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >decltype,result_of,还是typeof?

decltype,result_of,还是typeof?
EN

Stack Overflow用户
提问于 2010-05-04 16:28:53
回答 2查看 21.3K关注 0票数 12

我有:

代码语言:javascript
复制
class A {
public:
    B           toCPD() const;

和:

代码语言:javascript
复制
template<typename T>
class Ev {
public:
    typedef result_of(T::toCPD()) D;

在实例化Ev<A>之后,编译器会说:

meta.h:12:错误:'T::toCPD‘不是类型

decltype和typeof都不起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-05-04 17:09:41

因为您得到的结果取决于模板参数,所以typedef typename是必需的。

decltype是一个标准的C++11特性。它是一个“运算符”,接受一个表达式并返回一个类型。

代码语言:javascript
复制
typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic

如果T()不是有效的(T不是默认可构造的),您将需要declval,它是一个函数,它接受一个类型并返回该类型的一个无意义的无效值。declval只能在未计算的上下文中使用,如decltype

代码语言:javascript
复制
typedef typename decltype( std::declval<T>().toCPD() ) D;

在C++11之前,decltype是微软MSVC编译器的非标准扩展。标准化可能会稍微改变它的行为。

decltype类似,typeof是GCC在C++11之前的等效扩展,它也被克隆到其他编译器中。Here是来自于GCC的文档。该页面没有提供功能之间的比较,但它指出,当使用标准模式(-std=c++YY,您应该始终使用 do)时,必须将其称为-std=c++YY,并且它在C和C++中都可用。

为了与C语言兼容,__typeof__不会解析glvalue表达式中的引用类型。因此,它实际上只适用于C。这可能解释了为什么C++的特性没有继承更多不言而喻的名称: GNU不愿意牺牲向后兼容性,而微软不太关心C语言,可能需要更少的更改。

result_of是一个ISO元函数(从2006年开始在C++11 TR1库中进行标准化)。它是一个模板,它接受可调用类型(如函数int(void)、函数指针int(*)(void)、实现operator()的函数器类或指向成员函数的指针&T::toCPD)和该类型的参数类型列表,并在调用可以工作的情况下提供返回类型。

若要将result_of与指向成员函数的指针一起使用,必须在参数列表中包含父对象类型作为this的代理。

代码语言:javascript
复制
typedef typename std::result_of< decltype( & T::toCPD ) ( T * ) >::type D;

然而,这是非常脆弱的,因为如果有任何重载,比如非常量版本,&T::toCPD就不能被解析。尽管必须显式地写出T *T const *,但这是正确的!在大多数情况下,使用decltypedeclval会更好。

票数 34
EN

Stack Overflow用户

发布于 2010-05-04 16:58:49

result_of既不是函数,也不是运算符。result_of是一个元函数,具有作为模板参数的函数,并在成员类型上设置结果类型

代码语言:javascript
复制
typedef typename result_of<T::toCPD()>::type D;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2763824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档