c++ - declval<T>() 是否与 (*(T*)nullptr) 相同?

标签 c++ c++11 decltype

declval<T>()只是替换 (*(T*)NULL) 的旧技巧在 decltype 中获取 T 的实例而不需要担心 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 不仅仅是一个替代品,有什么区别,它在哪里有用?

最佳答案

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给出一个左值。

关于c++ - declval<T>() 是否与 (*(T*)nullptr) 相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14657092/

相关文章:

c++ - 来自 C++ 代码的 Shell 命令

c++ - 有没有办法限制 STL Map 的大小?

c++ - 在 C++ 中为基类和派生类声明 'virtual' 构造函数?

c++ - 如何返回 std::string.c_str()

c++ - SFINAE 有选择地纳入成员(member)

c++ - 如何使用 decltype 作为模板类返回类型的模板参数?

c++ - 合并排序链表

c++ - 链表的构造函数

ABI 错位名称中的 C++ 模板参数依赖 decltype

c++ - 如何在不假设任何构造函数的情况下获取构造函数和取消引用运算符(decltype)的类型?