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;
因为T1和T2是同一类型,所以会打印1。
如果declval不仅仅是一个替代品,有什么区别,它在哪里有用?
最佳答案
declval()
的优点是,如果在评估的上下文中使用它(即odr-used),则程序格式错误(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
将给出右值类型,而nullptr
将给出左值。