在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列表的修改(两个要点)仅是提议但不是官方标准的一部分?
这个问题是关于template<class...Types> class variant:
根据variant.variant/3,variant没有模板参数实例化的程序是错误的.
到目前为止,这么清楚.现在我有一个关于转换构造函数(template<class T> constexpr variant(T&& t) noexcept(see below))的问题:
variant.variant/variant.ctor-16.1表示转换构造函数不应参与重载决策,除非:
sizeof ...(类型)非零
(......以及我现在不关心的一些其他要求).
我的问题是,当variant没有模板参数已经使我的程序格式错误时,为什么还要关心我的转换构造函数是否参与重载决策?
看看MSVC和libstdc ++ - 实现variant它们实际上有一个enable_if_t<sizeof...(_Types) != 0>转换构造函数的声明.为什么?
给定以下类模板+特化:
template<class T = int>
struct S { static constexpr int value = 1; };
template<>
struct S<> { static constexpr int value = 2; };
Run Code Online (Sandbox Code Playgroud)
实例化时:
S<int>::value
Run Code Online (Sandbox Code Playgroud)
编译器使用value = 2实例化特化.我的问题是,为什么编译器会这样做?我不提供任何类型的案件的专业化吗?我认为我在理解默认模板参数时遇到问题.