gpt4 book ai didi

c++ - 从C++ 17开始的prvalue差异中的直接列表初始化与复制列表初始化与复制初始化的示例

转载 作者:行者123 更新时间:2023-12-02 09:49:27 29 4
gpt4 key购买 nike

对于这3种初始化形式(对于某些A类型)

A x = {<...>};
A x{<...>};
auto x = A{<...>};

自C++ 17以来的行为差异示例,除了w.r.t.显式ctor(显式ctor会破坏第一个)?

(由于C++ 17保证复制删除可以消除复制;
由于 auto ...,复制构造函数的隐式转换也不应在此处应用)

我一般都知道C++初始化形式是如何工作的,对于这个问题的广泛性/模糊性,我感到很抱歉,我只是想知道上面三种形式之间是否有任何(重大)区别,或者也许它们可以互换使用(区别除外)提到)。

最佳答案

我认为这里的差异很重要,尤其是由于隐式/显式差异,我相信您太快不敢理会了。

我要回答的问题与您提出的问题略有不同:为什么使用哪种形式?相对于:有什么区别?

A x = {<...>};

如果可以编译,请首选此格式。

如果rhs表达式具有可显式转换为 A的类型,则不会编译。那是一件非常好的事!这是该语言提供的安全功能。

类型作者通常(或至少应该)保留隐式构造/转换,以进行非常安全的转换。这样的转换应该是无损的,并且不会改变rhs和lhs之间表达的基本语义。例如: milliseconds x = 3s; rhs是 seconds,lhs是 milliseconds。并且构造在两个持续时间之间转换,并且完全不丢失任何信息。这是使用这种结构形式的好地方。

通过使用这种形式,程序员说:只给我 A类型的构造函数的“安全集”。如果rhs上的表达式类型有错误,可能导致不安全的转换,我想在编译时进行查找。

A是整数类型时,即使包括 {}也有一个优势:
unsigned x = {i};

这是遵循只给我安全转换的说法。但这给您的吊带带来了额外的麻烦:请给我带来无限的转换机会。 {}本质上是后者C++中的一个额外的权宜之计,以弥补几十年前C语言中的设计错误。

但是有时您需要更大的锤子。有时,明确的转换是您想要和需要的。现在是时候:
A x{<...>};

例如: milliseconds x{3};它将 int转换为 millisecond。尽管转换是无损的,但lhs的类型与rhs的类型不同。 rhs可以代表3个字。 3个苹果。 3国税局的通知。 3年。这不是一个隐式进行的安全转换。而且std::lib知道这一点。如果尝试过,它将无法编译。但是,有时候这正是您需要做的。为此情况保留此表格。

在某些情况下,不遵循此建议可能会导致运行时错误。 this lightning talk中演示了其中的两个。

最后,这是一个很好的形式:
auto x = A{<...>}; 

当您希望 x的类型为 A时。当 A并非易于拼写的类型,甚至不出现在rhs上时,它特别好。

我最喜欢使用这种形式的示例是在 std::chrono::round实现中:
template <class To, class Rep, class Period>
constexpr
To
round(const duration<Rep, Period>& d)
{
auto t0 = floor<To>(d);
auto t1 = t0 + To{1};
if (t1 == To{0} && t0 < To{0})
t1 = -t1;
auto diff0 = d - t0; // here
auto diff1 = t1 - d; // and here
if (diff0 == diff1)
{
if (t0 - duration_cast<To>(t0/2)*2 == To{0})
return t0;
return t1;
}
if (diff0 < diff1)
return t0;
return t1;
}

标记为“here and here”的行通常导致 diff0diff1的类型非常复杂:有两种不同的拼写方式。这是 common_type_v<duration<Rep, Period>, To>。对于代码的读者来说,确切地知道类型是什么并不重要。要知道的唯一重要的事情是,此类型将表示两个操作数的确切区别。

总之,这不是“最佳形式”。它们都是工具箱中的好工具。诀窍是知道何时使用哪个。而且,如果您擅长于此,那么您将比大多数C++程序员更加熟练。

关于c++ - 从C++ 17开始的prvalue差异中的直接列表初始化与复制列表初始化与复制初始化的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61470360/

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