我正在观看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
看起来很像上面的内容,但是由于没有评估任何东西,所以这些信息有什么用处。
答案 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中非常普遍。