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

Understanding how declval is working in the copy_assignment situation

本文关键字:情况下 工作 方式 assignment declval copy 了解      更新时间:2023-10-16

我正在看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&)。如果将int更改为unique_ptr,则此表达式将没有有效的类型,因为unique_ptr不可分配,从而导致类型替换失败,并从重载或专用化集中消除此模板。

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