在测试处理const
对象成员时,我遇到了clang中这个明显的bug。该代码在msvc和gcc中都能正常工作。然而,这个bug只出现在非const情况下,这显然是最常见的用法。我是否做错了什么,还是这真的是一个bug?
https://godbolt.org/z/Gbxjo19Ez
#include <string>
#include <memory>
struct A
{
// const std::string s; // Oddly, declaring s const compiles
std::string s;
constexpr A() = default;
constexpr A(A&& rh) = default;
constexpr A& operator=(A&& rh) noexcept
{
std::destroy_at(this);
std::construct_at(this, std::move(rh));
return *this;
}
};
constexpr int foo()
{
A i0{}; // call ctor
// Fails with clang. OK msvc, gcc
// construction of subobject of member '_M_local_buf' of union with no active member is not allowed in a constant expression { return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
i0 = A{}; // call assign rctor
return 42;
}
int main() {
constexpr int i = foo();
return i;
}
对于那些感兴趣的人,这是完整版本,将const对象转换为一级公民(可在向量、排序等中使用)。我非常不喜欢添加getter来维护不变性。