Visual C++中空类的std::movable评估为false,编译报错是否合规?
问题:C++20代码在MSVC编译失败,但GCC/Clang可正常编译运行
最简示例代码
#include <concepts> template<class T> struct MyContainer { MyContainer() = default; explicit MyContainer( std::size_t ) requires( std::default_initializable<T> ); void resize( std::size_t ) requires( std::movable<T> && std::default_initializable<T> ) {} }; struct A; struct B { MyContainer<A> c; }; struct A{}; int main() { B b; b.c.resize( 42 ); }
MSVC报错信息
<source>(18): error C7500: 'resize': no function satisfied its constraints <source>(7): note: could be 'void MyContainer<A>::resize(size_t)' <source>(7): note: the 'MyContainer<A>::resize' constraint was not satisfied <source>(7): note: the concept 'std::movable<A>' evaluated to false
分析与结论
这段代码是合法的C++20代码,编译错误属于MSVC的编译器实现问题。
具体原因:
- 结构体
A虽先做了前向声明,但在main函数调用resize时,A已经被完整定义。空结构体A会被编译器自动生成默认移动构造函数和移动赋值运算符,因此std::movable<A>概念的判断结果应为true,同时std::default_initializable<A>也成立,resize的约束条件完全满足。 - MSVC错误地在
A未完整定义的阶段(即实例化MyContainer<A>用于B的成员时)就检查了resize的约束,而非延迟到函数调用的实例化点(此时A已完整定义),这不符合C++标准对模板成员函数约束检查时机的要求。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

