从构造函数分配包含“std::string”的 ar 值时,clang 中存在明显错误

dou*_*oug 7 c++

在测试const对象成员的处理时,我在 clang 中遇到了这个明显的错误。该代码可在 msvc 和 gcc 中运行。然而,该错误仅出现在非常量中,这无疑是最常见的用途。我做错了什么还是这是一个真正的错误?

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;
}
Run Code Online (Sandbox Code Playgroud)

对于那些感兴趣的人,这是将 const 对象转换为一等公民的完整版本(可用于向量、排序等)。我真的不喜欢添加吸气剂来保持不变性。

https://godbolt.org/z/hx7f9Krn8

Art*_*yer 3

是的,这是一个 libstdc++ 或 clang 问题:std::string的移动构造函数不能在常量表达式中使用。下面给出了同样的错误:

#include <string>

constexpr int f() {
    std::string a;
    std::string b(std::move(a));
    return 42;
}

static_assert(f() == 42);
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/3xWxYW717

https://en.cppreference.com/w/cpp/compiler_support尚未显示 clang 支持 constexpr std::string