C++ decltype、result_of 还是 typeof?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2763824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:37:30  来源:igfitidea点击:

decltype, result_of, or typeof?

c++c++11type-inference

提问by Neil G

I have:

我有:

class A {
public:
    B           toCPD() const;

And:

和:

template<typename T>
class Ev {
public:
    typedef result_of(T::toCPD()) D;

After instantiating Ev<A>, the compiler says:

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

meta.h:12: error: 'T::toCPD' is not a type

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

neither decltype nor typeof work either.

decltype 和 typeof 都不工作。

回答by Potatoswatter

Since whatever result you obtain depends on the template parameter, typedef typenameis necessary.

由于您获得的任何结果取决于模板参数,因此typedef typename是必要的。

decltypeis a standard C++11 feature. It is an "operator" which takes an expression and returns a type.

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

typedef typename decltype( T().toCPD() ) D; // can't use T:: as it's nonstatic

If T()isn't a valid (Tnot default-constructible) you will want declvalwhich is a function that takes a type and returns a meaningless, invalid value of that type. declvalcan only be used in unevaluated contexts such as decltype.

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

typedef typename decltype( std::declval<T>().toCPD() ) D;

Before C++11, decltypewas a non-standard extension by Microsoft's MSVC compiler. Its behavior might have been changed slightly by standardization.

在 C++11 之前,decltype是 Microsoft 的 MSVC 编译器的非标准扩展。它的行为可能因标准化而略有改变。



typeofis GCC's equivalent pre-C++11 extension like decltype, which was also cloned in other compilers. Hereis its documentation from GCC. That page provides no comparison between the features, but it notes that typeofmust be called __typeof__when using a standard mode (-std=c++YY, which you should alwaysdo), and it is available in C as well as C++.

typeof是 GCC 等效的 pre-C++11 扩展,如decltype,它也在其他编译器中被克隆。是 GCC 的文档。该页面没有提供功能之间的比较,但它指出在使用标准模式时typeof必须调用__typeof__-std=c++YY,您应该始终这样做),并且它在 C 和 C++ 中可用。

For the sake of C compatibility, __typeof__will not resolve a reference type from a glvalue expression. So, it's really only suitable for C. This probably explains why the C++ feature didn't inherit the more self-explanatory name: GNU was unwilling to sacrifice backward compatibility, whereas Microsoft cares less about C and perhaps needed fewer changes.

出于 C 兼容性的考虑,__typeof__不会从泛左值表达式解析引用类型。所以,它真的只适用于 C。这可能解释了为什么 C++ 特性没有继承更不言自明的名称:GNU 不愿意牺牲向后兼容性,而 Microsoft 不太关心 C,可能需要更少的更改。



result_ofis a C++11 metafunction (previously standardized in the ISO TR1 library from 2006). It is a template which takes a callable type (such as a function int(void), function pointer int(*)(void), functor class implementing operator(), or pointer-to-member-function &T::toCPD) and an argument type-list for that type, and provides the return type if the call would work.

result_of是一个 C++11 元函数(之前在 2006 年的 ISO TR1 库中标准化)。它是一个模板,它采用可调用类型(例如函数int(void)、函数指针int(*)(void)、函子类实现operator()或指向成员函数的指针&T::toCPD)和该类型的参数类型列表,并在调用时提供返回类型工作。

To use result_ofwith a pointer to member function, you must include the parent object type in the argument list as a surrogate for this.

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

typedef typename std::result_of< decltype( & T::toCPD ) ( T * ) >::type D;

This is very brittle, though, because &T::toCPDcannot be resolved if there's any overloading, such as a non-const version. This is true despite the fact that T *or T const *must be explicitly written out! In most cases, you're better off with decltypeand declval.

但是,这非常脆弱,因为&T::toCPD如果有任何重载(例如非常量版本),则无法解决。尽管事实T *T const *必须明确写出,但这是真的!在大多数情况下,最好使用decltypedeclval

回答by Vicente Botet Escriba

result_of is not a function neither an operator. result_of is a meta-function having a function as templateparameter and setting the result type on the member type

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

typedef typename result_of<T::toCPD()>::type D;