c++ - 了解 declval 如何在 copy_assignment 情况下工作

标签 c++ c++11

我正在观看 Walter E. Brown 博士的模板元编程演讲。在他的演讲中,他为 is_copy_assignable 展示了这样的代码:

template<class U, class = decltype(declval<U&>() = declval<U const&>())>
static true_type try_assignment(U &&);

我遇到的问题是在这种情况下如何调用赋值运算符。当我尝试推理这段代码并说用虚拟类型代替时,说 int , 代替 U我得到:

template<class U, class = decltype(declval<int&>() = declval<int const&>())> template<class U, class = decltype(int& = int const&)>

所以我想知道这如何帮助我们确定赋值运算符是否有效。如果我明白declval正确地,这段代码甚至不会评估,那么如何从 int& = int const& 中确定呢? ,如果有或没有为 U 定义的赋值运算符,它甚至不会评估.

我知道在大多数情况下,复制赋值运算符将定义为

C& operator=(const C& other)

这看起来很像上面的内容,但仍然因为没有评估任何内容,那么这些信息有什么用。

最佳答案

我并没有真正按照您的意图执行以下步骤:

template<class U, class = decltype(declval<int&>() = declval<int const&>())>
template<class U, class = decltype(int& = int const&)>

declval说:假装返回模板参数类型的。我说假装是因为该函数并没有真正定义,只是声明了,所以它只能在未计算的上下文中使用。 decltype 内部是未评估的上下文,因为您只检查类型。

因此,表达式 decltype(declval<int&>() = declval<int const&>())基本上是在说:如果我有一个 int& , 称之为 x ,我有一个 int const& , 称之为 y , 表达式的类型是什么 x = y

正如您可能猜到的那样,这将调用赋值运算符,并且该表达式将具有有效类型(在本例中为 int& )。如果你改变 intunique_ptr ,此表达式将没有有效类型,因为 unique_ptr不可赋值,导致类型替换失败并从重载或特化集中删除此模板。

使用 declval 的原因是因为它允许您创建任何类型的值;这对于 a) 创建引用类型的东西,以及 b) 创建非引用类型而不假设它们具有例如默认构造函数。因此,使用 declval在高质量 TMP 中极为普遍。

关于c++ - 了解 declval 如何在 copy_assignment 情况下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615035/

相关文章:

c++ - 为什么C++类函数没有low_pc/high_pc DWARF信息

c++ - 如何扩展可变参数模板类

c++ - 为什么 C++ 中的 lambda 永远不会 DefaultConstructible

c++ - 创建可变数量的 std::threads

c++ - 读取访问冲突代码 : 0xCDCDCDE1 and Code :0xCDCDCDE1

c++ - 在派生中取消隐藏与基类具有相同名称和不同签名的某些函数

c# - 尝试从 C++/CLI 调用非托管 C++ 时解决错误

c++ - 使用 qsort 对 2D 数组进行排序 - 正确的类型转换

c++11 - MS ACCESS 中的 GRANT 支持

c++ - 在 C/C++ 中取消初始化变量