问题标签 [copy-initialization]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
4078 浏览

c++ - 为什么在使用初始化语法时没有调用转换运算符,为什么 clang 错误消息看起来不对?

我有以下代码,它使用显式转换构造函数构造一个对象 t2,该构造函数执行 t1 的隐式转换。这是意料之中的,并在第 3 版第 11.4.1 节的 C++ 编程语言中进行了描述。

如您所料:

但是,将 t2 的构造更改为初始化语法时:

Clang 输出以下内容:

我不知道初始化是否应该能够执行这样的隐式转换,但是错误消息似乎非常非常错误。没有从 'test1' 到 'string' 的已知转换,但它甚至显示了候选函数 operator string() {

是什么赋予了?C++ 标准对初始化构造函数中的隐式转换有什么看法?我认为这应该算作两次隐式转换,因此是不允许的,但编译器输出根本不建议这样做。

0 投票
2 回答
1844 浏览

c++ - 初始化对象时复制构造函数/赋值运算符混淆

这样做有什么区别:

根据我在此处阅读的内容,两者都使用复制构造函数,但我不明白为什么会发生这种情况以及隐式转换如何发挥作用。我如何理解它(在阅读之前)是第一个通过创建临时对象使用默认赋值运算符(如果未定义)然后调用复制构造函数,但这似乎是错误的。我之所以问,是因为我读到,当使复制构造函数显式时,即使某些东西是 class_name 类型,第一个选项也会失败,因此这两个选项必须足够不同。在第一个选项的复制构造函数之上使用赋值运算符(使用默认或用户定义的实现)还是只是调用复制构造函数的用户友好语法形式?

0 投票
1 回答
486 浏览

c++ - 这不是复制初始化,或者是吗?

在下面的代码中,我不允许声明显式ctor,因为编译器说我在复制初始化上下文(clang 3.3 和 gcc 4.8)中使用它。我试图通过使 ctor 不显式然后将复制构造函数声明为已删除来证明编译器是错误的。

编译器错了还是有其他解释?

更新一个不切实际但简单得多的版本

0 投票
1 回答
583 浏览

c++ - 复制列表初始化是否在概念上调用复制ctor?

A a = 1;在 C++11 之前,我们可以通过编写类似于A a = A(1);. 也就是说,首先创建一个临时对象,然后调用一个复制 ctor。无论复制省略如何,这在概念上都必须如此,并且复制 ctor 必须是可访问的。

使用 C++11 中的列表初始化,我们可以通过编写A a = {1, 2};. 在我看来,这应该或多或少等同于A a = A(1, 2);. 但是,在 GCC 和 clang 上,A a = {1, 2}即使复制和移动 ctor 不可访问(通过声明为私有)也可以编译。尽管如此,A a = 1;如果相应的复制/移动 ctor 不可访问,则不会在 GCC 或 clang 上编译。因此,A a = {1, 2};似乎或多或少等同于A a{1, 2};直接列表初始化。这与真正的直接列表初始化之间的区别在于,A a = {1, 2};如果采用两个 int 的 ctor 是显式的,则不会编译。在这方面,A a = {1, 2};类似于复制初始化。

所以,我的问题是:A a = {1, 2};概念上的表达式的确切语义是什么?从概念上讲,复制省略不会妨碍您。

0 投票
2 回答
1721 浏览

c++ - 显式和非显式构造函数

我观察到不同的输出。案例 1:当第 1 行和第 2 行被注释时,o/p 是:构造函数调用构造函数调用

情况 2:当第 1 行和第 2 行未注释时:则编译错误

有人可以解释输出及其原因。也有人可以判断 operator= 是否实际上最终调用了复制构造函数。

0 投票
1 回答
511 浏览

c++ - 隐式类类型转换是否使用复制构造函数?

我的 C++ 书中的以下引用:

当我们使用直接初始化时,我们要求编译器使用普通函数匹配来选择与我们提供的参数最匹配的构造函数。当我们使用复制初始化时,我们要求编译器将右手操作数复制到正在创建的对象中,并在必要时转换该操作数。

对我来说,这个粗体字会产生一些歧义。例如,这听起来像是将右侧的操作数转换为类类型,然后使用了复制构造函数;

会成为...

它使用复制构造函数。如果这是真的,那么我的测试程序;

应该产生“第二种方式,第二种方式,第一种方式”。然而,它改为打印“第二种方式,第二种方式”。由此我会得出结论,它使用的是 const char* 构造函数而不是复制构造函数。我会很好的,除非后来它说...

在复制初始化期间,允许(但不是必须)编译器跳过复制/移动构造函数并直接创建对象。即允许编译器重写

进入

然而,即使编译器省略了对复制/移动构造函数的调用,复制/移动构造函数也必须存在并且必须在程序中的那个点是可访问的(例如,不是私有的)。

我不确定为什么复制构造函数甚至需要在这些示例中提及,不是

总是隐含地意味着无论如何都在使用 const char* 构造函数?实际上,需要定义复制构造函数才能使上述内容起作用,这对我来说意义不大。但是,如果我将“const A&”构造函数设为私有(其余为公共),那么我的程序将无法运行。为什么必须为甚至不涉及它的隐式转换定义复制构造函数?"string null_book = "9-999-99999-9"" 使用什么构造函数?

0 投票
1 回答
370 浏览

c++ - 通过不明确的转换运算符进行引用绑定

clang 和 gcc 都给出了模棱两可的转换运算符,但 Visual Studio 编译正常并打印“operator const CL2&”。根据标准,必须如何正确?
正如我所理解的,将 CL1 转换为 const CL2& 是在复制初始化上下文中(作为 cl2 对象直接初始化的一部分)。我看过 n4296 草案,[over.match.copy]:

假设“cv1 T”是被初始化对象的类型,T是类类型,候选函数的选择如下:
— T的转换构造函数(12.3.1)是候选函数。
— 当初始化表达式的类型是类类型“cv S”时,考虑 S 及其基类的非显式转换函数。初始化临时绑定到构造函数的第一个参数时,其中参数的类型为“对可能 cv 限定的 T”的引用,并且在直接初始化类型对象的上下文中使用单个参数调用构造函数“cv2 T”,还考虑了显式转换函数。那些没有隐藏在 S 中并产生其 cv 非限定版本与 T 相同类型或者是其派生类的类型是候选函数。返回“对 X 的引用”的转换函数根据引用的类型返回类型 X 的左值或 x 值,因此在选择候选函数的过程中被认为产生 X。

即两个转换运算符都被视为返回 CL2 和 const CL2(不仅仅是没有 const 的 CL2),还有待解决,哪种转换更好:CL2 -> const CL2& 或 const CL2 -> const CL2&。第二种情况似乎更合适。在这种情况下是否应该考虑更好的资格转换?或者两种情况都是身份转换?我在标准中找不到它

0 投票
2 回答
44 浏览

c++ - 转换运算符绕过派生类型的构造函数并跳到基类型的复制初始化?

转换运算符在以下代码中的行为方式存在问题:

我在通话 2) 中收到错误:

所以问题是:它到底为什么要复制初始化A?注意,B 声明了它自己的复制构造函数。我认为成功的调用 1) 与 2) 相同,但显然不是?

关于我正在尝试解决的实际问题:CI 类中想要提供到第三方 A 类的转换,该类禁止复制。这个想法是返回一个代理 B : A ,它将在 A 之上添加移动语义。是否有另一种方法来定义转换运算符以在遵守其非复制策略的同时将 A 放入堆栈。

0 投票
0 回答
33 浏览

c++ - 为什么我们在复制和直接初始化之间有所不同?

我有以下问题,希望你能帮助我。代码:

为什么我们在这些初始化之间有所不同?

我认为在这种情况下两者都是相同的,因为每次调用复制构造函数。还是我们不同,因为在 2) 中可以进行隐式转换?

但我读到,在这种情况下,我们的初始化也有所不同:

为什么这些不同的初始化?先感谢您!

0 投票
2 回答
797 浏览

c++ - 删除复制构造函数中的 const

这就是我最初所做的。

但是,如果将 A 类稍微修改如下(删除复制构造函数中的 const),为什么最后一行会出现编译错误?谢谢你