wal*_*rii 23 c++ decltype c++11
是declval<T>()只为老把戏的替代品(*(T*)NULL),以获得T的实例在decltype,而无需担心T的构造函数?
以下是一些示例代码:
struct A {};
struct B {
    A a;
};
typedef decltype((*(B*)nullptr).a) T1;
typedef decltype(declval<B>().a) T2;
cout << "is_same: " << is_same<T1, T2>::value << endl;
打印1,因为T1和T2是相同的类型.
如果declval不仅仅是替代品,那么差异是什么?它在哪里有用?
eca*_*mur 28
declval()具有以下优点:如果在评估的上下文中使用(即,使用了odr),则程序形成不良(20.2.4p2),并且需要发布诊断(每1.4p1).通常,这是通过static_assert库中的强制执行的:
c++/4.7/type_traits: In instantiation of '[...] std::declval() [...]':
source.cpp:3:22:   required from here
c++/4.7/type_traits:1776:7: error: static assertion failed: declval() must not be used!
declval 也适用于引用类型:
using S = int &;
using T = decltype(std::declval<S>());
using U = decltype(*(S *)nullptr);  // fails
如果类型不是引用类型,declval则给出一个rvalue类型,其中nullptr给出一个左值.
不,declval<T>()不一样(*(T*)nullptr).而且decltype(expr.bar)不一样decltype((expr.bar)).
前者比较表达式.后者使用decltype检查表达式和前者使用decltype检查声明的类型expr.bar.因此,您必须使用decltype操作数来对类型进行有用的比较,您会发现它们是不同的.
struct A {};
struct B {
    A a;
};
// E1: B().a 
// E2: declval<A>().a
// E3: (*(B*)0).a
// E4: ((B&&)(*(B*)0)).a
在这4个表达式中,所有表达式都有类型A.E1是一个prvalue(在C++ 14中它是一个xvalue.有些编译器可能会将它视为xvalue,即使在它的C++ 11模式下),E2也是一个xvalue.E3是一个左值,又E4是一个x值.
// T1: decltype((*(B*)0).a)
// T2: decltype(((*(B*)0).a))
在这两种类型中,第一个decltype给出了由表达式命名的成员的类型.所述构件具有类型A,所以T1是A.第二个decltype产生表达式的类型,&如果表达式是左值则修改,&&如果表达式是xvalue则修改.表达式是左值,T2也是A&.
| 归档时间: | 
 | 
| 查看次数: | 2745 次 | 
| 最近记录: |