我正在观看 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 中极为普遍。
关于c++ - 了解 declval 如何在 copy_assignment 情况下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615035/