问题描述
如果你看下面的代码,我认为 main()
中的两行应该调用 initializer_list
InitSomething
的构造函数。 gcc输出 22
如我所料,但是clang只输出一个 2
。铛是错的?
我正在编译 -std = c ++ 14
。
#include< iostream>
struct InitSomething {
explicit InitSomething(int){std :: cout<< 1’ ; }
InitSomething(std :: initializer_list< int>){std :: cout<< 2’ ; }
操作符int(){return 1; }
};
int main(){
InitSomething init_something {1};
InitSomething init_something_else {init_something};
输出 clang ++ --version
(我在Mac上)是
Apple LLVM版本7.3.0(clang-703.0.31)
目标:x86_64-apple-darwin15.5.0
线程模型:posix
InstalledDir:/Applications/Xcode.app/Contents/Developer/Toolchains/ XcodeDefault.xctoolchain / usr / bin
和 g ++ --version的输出
在我提到的另一个平台上是
g ++(GCC)4.8.5 20150623(Red Hat 4.8 .5-4)
Copyright(C)2015 Free Software Foundation,Inc.
这是免费软件;请参阅复制条件的来源。没有任何b $ b保修;甚至不适用于适销性或针对特定用途的适用性。
DR1467的标题涉及聚合,但的措辞为如果 T
是一个类的类型,并且第一个项目符号不限于聚合:
然而,从这句话中走了回来(用聚合类替换类类型),所以清楚地表明,如果可行的话,initializer-list构造函数是首选的: b
$ b
所有关于排名隐式转换序列的讨论都是无关紧要的,因为非初始化列表构造函数甚至不是候选人。
Clang在DR1467之后和DR2137之前实施措辞。
If you look at the following code, I think that both the lines in main()
should call the initializer_list
constructor for InitSomething
. gcc outputs 22
as I expected, but clang just outputs a single 2
. Is clang wrong?
I am compiling with -std=c++14
.
#include <iostream>
struct InitSomething {
explicit InitSomething(int) { std::cout << '1'; }
InitSomething(std::initializer_list<int> ) { std::cout << '2'; }
operator int() { return 1; }
};
int main() {
InitSomething init_something{1};
InitSomething init_something_else{init_something};
}
The output of clang++ --version
(I am on a mac) is
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
and the output of g++ --version
on the other platform I mentioned is
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
DR1467's title concerns aggregates, but the wording it added to [dcl.init.list]/3 as the first bullet is not limited to aggregates:
However, DR2137 walked back from this wording (replacing "a class type" with "an aggregate class"), and so this bullet no longer applies to non-aggregates like InitSomething
.
Instead, [dcl.init.list]/3.6 applies, like it did pre-DR1467:
And [over.match.list] makes clear that initializer-list constructors are preferred if at all viable:
All this talk about ranking implicit conversion sequences is irrelevant because the non-initializer-list constructors are not even candidates.
Clang is implementing the wording after DR1467 and before DR2137.
这篇关于Clang跳过初始化程序列表结构的处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!