作者LPH66 (かつて交わした约束)
看板C_and_CPP
标题Re: [问题] G++ and VC++ Constructor 问题
时间Thu Jun 1 23:22:31 2017
: → ROGZ: 还有,VC是没问题的, 是g++不行 06/01 22:55
没仔细看原文 (趴
g++ 给的错误讯息是
error: conversion from 'const char*' to non-scalar type 'A' requested
这句话在这里有点摸不着头到底为什麽
不过拿一些相关的关键字下去 google 时却让我发现一件事:
A a = "123"; 这个语法其实是
Copy Initialization 而不是
Direct Initialization
A a("123"); 这个才是 Direct Initialization
两者之间的差别在於, copy initialization 做的是复制
因此它会把 = 右边的东西先转成左边型态之後呼叫 copy ctor 复制过去 (至少语意上)
发生错误的地方就是「转」这个动作
一边是个 const char * 另一边是个物件
所以会去看物件方有没有目标方定义的转换, 也就是吃这种型态的 ctor
但 A 并没有吃 const char * 的 ctor 所以转不动出现错误
这一切在 Direct Initialization 都不会发生
因为那是直接抓 A 的 ctor 做 overload resolution 所以可以隐式转
更多关於此两者的差别可以看 GotW #36
http://www.gotw.ca/gotw/036.htm
VC++ 可以过的原因可能是它把这两者混在一起了...
====
那所以如果 = 右边的东西是个 string 就可以过了
因为这下右边能够「转」成左边所以什麽事都没有
例如以下都是 OK 的:
A a2 = string("123");
A a3 = "123"s; // 这是 C++14 的标准 literal suffix
// 需要 using namespace std::literals;
// 且要对 g++ 下 --std=c++14
// 特点就是虽然写 "" 但型态却是 string 而非 const char *
--
◢ ˊ_▂▃▄▂_ˋ. ◣ ▅▅ ▅▅ ι●╮ █
▄▄▄▄▄
▍
./◤_▂▃▄▂_◥ \'▊ HARUHI █████ <■┘ ▄▄▄▄▄▄▄
▎
⊿ ◤◤◥█◥◥█Δ ISM By-gamejye ¢|\ ▌▌▌▌▌▄▌▌
▏
ζ(▏●‵◥′●▊)Ψ ▏ █
⊿Δ ▄▄▄ ▄▄▄▄
█/|▊ 〃 、 〃▋ |\ ▎ ハルヒ主义 █
▄▄▄█▄▄
◥◥|◣ ‵′ ◢/'◢◢
S.O.S 世界を大いに盛り上げるための凉宫ハルヒの団
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.177.29.238
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1496330554.A.570.html
1F:→ Killercat: 诶,要14喔 XD 我以为这东西是11的 06/01 23:23
2F:→ Killercat: 另外我一时眼残看错 拍写 XD 06/01 23:24
※ 编辑: LPH66 (180.177.29.238), 06/01/2017 23:24:57
3F:→ LPH66: literal suffix 在 11 就有了, 但 ""s 是 14 才有 06/01 23:25
4F:→ LPH66: 11 没有定义标准的 literal suffix 06/01 23:26
5F:推 ROGZ: 感谢您的解答 06/01 23:50
6F:→ ROGZ: 但虽然说是Copy Initialization,但试着写一下Copy Construc 06/01 23:52
7F:→ ROGZ: tor和overload assignment operator後,却发现它都没有使用 06/01 23:54
8F:→ ROGZ: 到,所以原则上来说A a = string("123")和A a("123")是执行 06/01 23:57
9F:→ ROGZ: 类似的动作去construct A吧 06/01 23:58
10F:→ ROGZ: 但是,A a("123")能把"123"视为string,而A a = string("123 06/02 00:02
11F:→ ROGZ: ")却只能视为const char* 06/02 00:02
12F:→ ROGZ: 上面写错了,应该是A a = "123",被视为const char* 06/02 00:07
13F:→ djshen: 不是视为string 是implicit conversion 06/02 00:20
14F:→ djshen: en.cppreference.com/w/cpp/language/copy_initialization 06/02 00:24
15F:→ djshen: 有提到the implicit conversion in copy-initialization 06/02 00:24
16F:→ djshen: must produce T directly from the initializer 06/02 00:24
17F:→ djshen: 还有The equals sign, =, in copy-initialization of a 06/02 00:25
18F:→ djshen: named variable is not related to the assignment 06/02 00:25
19F:→ djshen: operator 06/02 00:25
20F:→ ROGZ: 感谢djshen大的资料,有比较了解了 06/02 00:29
21F:→ hunandy14: 同问 int i=0; 与 int i(0); 前者也是有复制? 06/02 00:49
22F:→ hunandy14: 在C上後者并不能这样写 06/02 00:50
23F:→ hunandy14: 是否只在 C++ 才具 copy init 在 C 是 D init? 06/02 00:51
24F:→ hunandy14: 或是 两者都是 copy init 06/02 00:51
25F:推 steve1012: 用=会呼叫copy constructor. C没有研究但c没有construc 06/02 01:22
26F:→ steve1012: tor 吧 06/02 01:22
27F:→ djshen: built-in type就直接standard conversion了吧? 06/02 01:36
28F:推 steve1012: 对耶是int 06/02 03:27
29F:推 boy770329: A="123"在有支援copy elision的compiler是不会做copy 06/02 08:04
30F:→ boy770329: 的吧 06/02 08:04
31F:→ LPH66: > 没有呼叫 ctor 的问题 06/02 10:06
32F:→ LPH66: 这就是为什麽我原文加了个 (至少语意上) 的括号 06/02 10:07
33F:→ LPH66: 因为这里是标准允许实作可以不 copy 的地方 06/02 10:07
34F:→ LPH66: (即是所谓的 copy elision) 06/02 10:07
35F:→ LPH66: 当要 copy 的来源物件是个刚生成的物件时 06/02 10:08
36F:→ LPH66: 标准允许这里跳过一次复制让那物件在复制目的地直接生成 06/02 10:09
37F:→ james1022jk: ctor在单一引数时有一些规则 06/02 11:16
38F:→ loveflames: 函数返回也有一样的问题 06/02 11:58
39F:→ hunandy14: 了解~感谢 06/03 14:15