【问题标题】:Does clang++ 12 support C++20 std::construct_at?clang++ 12 是否支持 C++20 std::construct_at?
【发布时间】:2020-09-26 04:01:55
【问题描述】:

我正在使用最近批准的 C++20 标准功能 std::construct_at() 并尝试更熟悉它们...

我已经基于example from CppReference.com 构建了一个示例:

#include <memory>

struct S {
    int a;
    int b;
};

int main() {
    std::allocator<S> alloc;
    S * s = alloc.allocate(1);
    std::construct_at(s, 42, 43); // GCC 10.2 OK Clang 12 NOT
    std::destroy_at(s);
    alloc.deallocate(s, 1);
    s = nullptr;
}

上面的代码使用最新的稳定 GCC 构建良好: gcc-10.2 test.cpp -std=c++2a -lstdc++

但我无法使用 Clang 12(主干)或 10(稳定)编译它。 clang-12 test.cpp -std=c++20 -stdlib=libc++ 有错误:

test.cpp:11:5: error: no matching function for call to 'construct_at'
    std::construct_at(s, 42, 43); // GCC 10.2 OK Clang 12 NOT
    ^~~~~~~~~~~~~~~~~
/usr/local/clang/bin/../include/c++/v1/memory:903:16: note: candidate template ignored: substitution failure [with _Tp = S, _Args = <int, int>]: no matching constructor for initialization of 'S'
constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
               ^
1 error generated.

我是否错误地使用了参数包? Clang C++20 feature list 似乎还没有表明它受支持? 我在 Clang 中尝试过使用 GCC 工具链,结果相同:--gcc-toolchain=/usr/local/gcc-10.2.0

我通过在线编译器浏览器获得了类似的结果。

如果我通过初始化列表显式构造一个 S(这很可能会破坏就地构造的目的)std::construct_at(s, S{42, 43});,那么程序会编译但链接失败。

这种方法是否构建了一个暂时的破坏了construct_at的目的? 如果我添加一个 std::move 怎么办? std::construct_at(s, std::move(S{42, 43})); 在线编译器浏览器似乎表明移动需要更多的汇编,也许没有它会有一个省略(我通过添加移动制造了一种悲观情绪)?

链接错误是:

/usr/bin/ld: /tmp/test-b07239.o: in function `std::__1::__throw_length_error(char const*)':
test.cpp:(.text._ZNSt3__120__throw_length_errorEPKc[_ZNSt3__120__throw_length_errorEPKc]+0x12): undefined reference to `__cxa_allocate_exception'
/usr/bin/ld: test.cpp:(.text._ZNSt3__120__throw_length_errorEPKc[_ZNSt3__120__throw_length_errorEPKc]+0x30): undefined reference to `typeinfo for std::length_error'
/usr/bin/ld: test.cpp:(.text._ZNSt3__120__throw_length_errorEPKc[_ZNSt3__120__throw_length_errorEPKc]+0x3a): undefined reference to `std::length_error::~length_error()'

显然-stdlib=libc++should be used linked with an ABI-lstdc++解决了链接错误,而-lc++abi仍然未命中:

/usr/bin/ld: /tmp/test-bb0950.o: in function `std::length_error::length_error(char const*)':
test.cpp:(.text._ZNSt12length_errorC2EPKc[_ZNSt12length_errorC2EPKc]+0x23): undefined reference to `std::logic_error::logic_error(char const*)'

难道我还缺少另一个用于 logic_error 的库?

回到手头的关键问题:

  • Clang 是否支持std::construct_at(s, 42, 43);
  • 使用初始化列表构造是否会影响性能?有/无移动?

【问题讨论】:

  • 很少有人可以访问clang++12(我自己也是 9 岁)如果您尝试语言中的 HEAD 功能,事情将会改变.

标签: c++ clang++ c++20


【解决方案1】:

这与construct_at 无关。 S 是一个聚合;在其默认构造函数和复制/移动构造函数之外,它没有要调用的构造函数。所以S只能通过聚合初始化用值来构造。

这通常需要一个花括号初始化列表(例如:S{3, 5})。但是 C++20 包含一个特性,允许聚合初始化通过构造函数语法(例如:S(3, 5))只要参数不会调用默认或复制/移动构造函数(在这种情况下,它会调用一个其中)。

但是 Clang doesn't implement that feature as of yet。所以construct_at 构造聚合失败。

【讨论】:

  • 我喜欢人们现在的这些东西! “std::construct_at(s, 42, 43); // GCC 10.2 OK Clang 12 NOT”+1
  • 相关参考可能是:P0960R3
  • 从站在现代 C++ 创新的最前沿 Clang/libc++ 开发最近似乎步履蹒跚。它仍然缺乏完整的 C+17 支持,甚至远远落后于 C++20。一年前的 C++20 PR 似乎还没有人关注。我想知道适当的概念支持是否最终会使这些问题对知识较少的人更具可读性。
猜你喜欢
  • 2020-12-22
  • 2023-03-05
  • 2020-12-20
  • 2023-03-08
  • 2022-01-07
  • 1970-01-01
  • 2021-05-24
  • 2021-10-03
  • 1970-01-01
相关资源
最近更新 更多