了解declval在copy_assignment情况下的工作方式

时间:2018-02-05 02:21:27

标签: 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&来确定是否存在为{{1定义的赋值运算符}}

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

U

看起来很像上面的内容,但是由于没有评估任何东西,所以这些信息有什么用处。

1 个答案:

答案 0 :(得分:1)

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

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&)。如果您将int更改为unique_ptr,则此表达式不会具有有效类型,因为unique_ptr不可分配,导致类型替换失败并从重载中删除此模板或专业化。

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