在cppreference(4)上,转换构造函数描述如下:
转换构造函数.如果同时在范围内的每个from 都存在虚函数的重载,则构造一个包含替代类型的变体,该替代类型
T_j将通过表达式F(std::forward<T>(t))的重载决策选择,除了:F(T_i)T_iTypes...
F(T_i)仅当声明T_i x[] = { std::forward<T>(t) };对某些发明变量有效时才考虑重载x;- 如果
T_i是(可能是cv-qualified)bool,F(T_i)则仅考虑是否std:remove_cvref_t<T>也是bool.
我对关于这个问题的第二个要点特别感兴趣bool.在它的例子中说:
std::variant<std::string, bool> y("abc"); // OK, chooses string; bool is not a candidate
我现在用clang 7.0.0(godbolt),gcc.8.2(godbolt)和VS2017 测试了相同的代码.我想知道为什么包含的替代类型是bool(对于所有三个编译器)而不是cppreference描述的std :: string.这是所有三个编译器的标准库中的错误吗?
我还发现了以下文件:P0608R3.这是否意味着,cppreference列表的修改(两个要点)仅是提议但不是官方标准的一部分?
Bar*_*rry 11
P0608R3在圣地亚哥采用.其措辞适用于工作草案 - 您可以在[variant.ctor]/12中看到新的措辞.
作为改变的一部分,激励的例子:
variant<string, bool> x = "abc";
Run Code Online (Sandbox Code Playgroud)
现在是否持有string(在c ++ 20中),而它曾经持有bool(在c ++ 17中).此示例的含义在标准版本之间更改.
只是没有一个标准库已经实现了这个改变.这是非常近.它在libstdc ++和libc ++页面中都列为不完整.但正如您所看到的,还有大量的C++ 20功能尚未实现.好消息是,它仍然是2019年初,并且有足够的时间.
每个版本的C++标准都有错误.数以百计.
C++实现旨在有用,因此他们不会盲目地遵守已发布的标准文本.没有理由保持与一张纸的bug-for-bug兼容性.
(作为一个极端的例子,在C++ 17之前,标准在技术上要求将<int>in std::vector<int> v;解析为头名,然后因为它不在#include指令内而被拒绝.应该不用说没有编译器会这样做.)
Cppreference也旨在有用.所以我们也没有保持与bug标准的bug-for-bug兼容性.当一篇文章首次出现在ISO出版的一篇论文中时没有用处(标准历史学家除外); 作为程序员,我们关心的是我们在使用时获得的-std=c++17,或者无论您的实现等效标志是什么.因此,我们的文档是针对每个C++标准的假设完整和正确实现以及适用于该标准的所有后续错误修正和说明.*我们使用当前的实现作为这种假设实现将做什么的证据.
当特定更改没有当前实现时,我们会评估更改的性质,以预测实现如何处理它.意在追溯核心语言的变化被标记为缺陷报告,使通话更容易(虽然有时他们没有达到回所有的方式,这是不是在标签).但是,图书馆更改并未附带一致的"DR"标签,因此呼叫更多取决于我们.
在这种特殊情况下,虽然P0608没有被标记为缺陷报告,但它在发布后很快就纠正了C++ 17中一个极其可疑的行为.另外,对于代码来说,非常不希望根据标准模式std::variant<std::string, bool> x = "abcd";静默地改变相同实现的含义.依赖的代码std::variant在野外也是不常见的(这也是委员会甚至首先批准"破坏"变更的部分原因).因此,我预测该论文最终将被追溯应用并相应地记录.
*这是几年前的哲学变革; 因此,我们仍然有很多案例,其中错误修复在文档中不被视为追溯,但应该是.随着时间的推移,他们正在慢慢清理.