gpt4 book ai didi

c++ - 当 static_cast'ing 为仅移动类型时,Clang 与 GCC

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:27:46 24 4
gpt4 key购买 nike

考虑以下简单的仅移动类:

struct bar {
constexpr bar() = default;
bar(bar const&) = delete;
bar(bar&&) = default;
bar& operator=(bar const&) = delete;
bar& operator=(bar&&) = default;
};

现在,让我们创建一个包装器:

template <class T>
struct box {
constexpr box(T&& x)
: _payload{std::move(x)}
{}

constexpr explicit operator T() &&
{
return std::move(_payload);
}

private:
T _payload;
};

还有一个测试:

int main()
{
auto x = box<bar>{bar{}};
auto y = static_cast<bar&&>(std::move(x));
}

如果使用 -std=c++14 或更高版本编译,Clang-6.0 对这段代码很满意。然而,GCC-8.1 会产生以下错误:

<source>: In function 'int main()':
<source>:29:45: error: invalid static_cast from type 'std::remove_reference<box<bar>&>::type' {aka 'box<bar>'} to type 'bar&&'
auto y = static_cast<bar&&>(std::move(x));

这是一个 link to compiler explorer尝试一下。

所以我的问题是,谁对谁错?

最佳答案

简化示例:

struct bar 
{
bar() = default;
bar(bar const&) = delete;
bar(bar&&) = default;
};

struct box
{
explicit operator bar() && { return bar{}; }
};

int main() { static_cast<bar&&>(box{}); }

live on godbolt.org


首先,让我们看看转换运算符是显式意味着什么:

A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.

static_cast 是否被视为直接初始化

The initialization that occurs in the forms

T x(a);
T x{a};

as well as in new expressions, static_­cast expressions, functional notation type conversions, mem-initializers, and the braced-init-list form of a condition is called direct-initialization.


由于 static_cast直接初始化,转换运算符是否标记为 explicit 并不重要。但是,删除 explicit 会使代码在 g++clang++ 上编译:live example on godbolt.org .

这让我相信这是一个 g++ 错误,因为 explicit 在这里有所作为......当它不应该的时候。

关于c++ - 当 static_cast'ing 为仅移动类型时,Clang 与 GCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50430149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com