带有矛盾requires约束的拷贝构造函数相关技术咨询
带有矛盾requires约束的拷贝构造函数相关技术咨询
嘿,咱们来聊聊这段有点“自相矛盾”的C++代码,它的问题核心就出在拷贝构造函数的requires约束上,简直是自己绕自己的典型例子:
这段代码里,
struct S的拷贝构造函数被加上了一个特别的约束——要求当前类不满足可拷贝构造:
#include <concepts> template <typename T> struct S { S() = default; S(const S &) requires (!std::copy_constructible<S>) {} }; S<int> u; S<int> v(u); // 尝试触发拷贝构造 static_assert( !std::copy_constructible<S<int>> );
咱们来拆解这里的矛盾点:
- 首先,
std::copy_constructible这个C++20概念的判断逻辑,是看目标类型是否拥有一个可用的拷贝构造函数(不管是编译器合成的,还是用户自定义的)。 - 但这里的拷贝构造函数,它的存在与否(是否满足约束),又反过来依赖于
!std::copy_constructible<S<T>>的结果——这就形成了循环依赖的判断死结。 - 当我们写
S<int> v(u);尝试拷贝构造时,编译器得先判断这个带约束的拷贝构造函数是否可用:它需要先确定std::copy_constructible<S<int>>是false,但这个判断本身又需要知道“有没有可用的拷贝构造函数”,完全是鸡生蛋还是蛋生鸡的问题。 - 最后那个
static_assert断言它不是可拷贝构造的,实际编译结果可能会因编译器而异:有些编译器会把这个带循环约束的拷贝构造函数视为不可用,此时std::copy_constructible<S<int>>会返回false,断言通过;但这种写法本身逻辑上就是拧巴的,绝对不能在实际项目里这么写。
总的来说,这是一个典型的概念判断与成员函数约束形成循环依赖的反例,属于逻辑自洽性出问题的写法,实际开发中一定要避开这种坑。
内容来源于stack exchange
相关产品推荐
相关产品推荐

