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
decltype, result_of, or typeof?
提问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 typename
is necessary.
由于您获得的任何结果取决于模板参数,因此typedef typename
是必要的。
decltype
is 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 (T
not default-constructible) you will want declval
which is a function that takes a type and returns a meaningless, invalid value of that type. declval
can only be used in unevaluated contexts such as decltype
.
如果T()
不是有效的(T
不可默认构造的),您将需要declval
which 是一个接受类型并返回该类型的无意义、无效值的函数。declval
只能在未评估的上下文中使用,例如decltype
.
typedef typename decltype( std::declval<T>().toCPD() ) D;
Before C++11, decltype
was a non-standard extension by Microsoft's MSVC compiler. Its behavior might have been changed slightly by standardization.
在 C++11 之前,decltype
是 Microsoft 的 MSVC 编译器的非标准扩展。它的行为可能因标准化而略有改变。
typeof
is 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 typeof
must 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_of
is 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_of
with 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::toCPD
cannot 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 decltype
and declval
.
但是,这非常脆弱,因为&T::toCPD
如果有任何重载(例如非常量版本),则无法解决。尽管事实T *
或T const *
必须明确写出,但这是真的!在大多数情况下,最好使用decltype
和declval
。
回答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;