在对向量的初始化中
std::vector<std::pair<int, std::string>> foo{{1.0, "one"}, {2.0, "two"}};我该如何解释foo的结构?据我理解,
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );是首选和选择的。std::initializer_list<T>的模板参数导出为std::pair<int, std::string>。foo的每个元素都是一个std::pair。但是,std::pair没有重载接受std::initializer_list。对于第三步,我不太确定。我知道内部大括号不能被解释为std::initializer_list,因为它们是异质的。标准中实际构建foo每个元素的机制是什么?我怀疑答案与将内部大括号中的参数转发到重载template< class U1, class U2 pair( U1&& x, U2&& y );有关,但我不知道这是什么。
编辑
我想问同样的问题的更简单的方法是:
std::map<int, std::string> m = { // nested list-initialization
{1, "a"},
{2, {'a', 'b', 'c'} },
{3, s1}如the首选项示例中所示,在标准中,它表示{1, "a"}、{2, {'a', 'b', 'c'} }和{3, s1}分别被转发给std::pair<int, std::string>的构造函数
发布于 2020-05-27 09:32:45
通常,表达式是从内到外分析的:内部表达式有类型,然后这些类型决定外部操作符的含义和要调用的函数。
但是初始化程序列表不是表达式,也没有类型。因此,内-外不工作.需要特殊的过载解析规则来解释初始化程序列表。
第一条规则是:如果存在一个参数为initializer_list<T>的构造函数,那么在第一轮过载解析中,只考虑此类构造函数(over.match.list)。
第二条规则是:对于每个initializer_list<T>候选项(每个类可能有一个以上的候选项,每个类都有不同的T ),检查每个初始化器是否可以转换为T,并且只有那些候选项保留在这个结果(over.ics.list)中。
这第二个规则基本上是,其中的初始化-列表-有-没有类型的障碍是采取和内-外分析被恢复。
一旦重载解析决定了应该使用特定的initializer_list<T>构造函数,就会使用复制初始化来初始化初始化器的列表。
发布于 2020-05-27 08:19:07
您混淆了两个不同的概念:
1)初始化器列出
initializer_list<T>**:**,主要用于集合的初始化。在这种情况下,所有成员都应该是同一类型的。(不适用于std::pair)
示例:
std::vector<int> vec {1, 2, 3, 4, 5};
2)统一初始化
在Uniform initialization:中,大括号用于构造和初始化一些对象,如structs、类(带有适当的构造函数)和基本类型(int、char等)。
示例:
struct X { int x; std::string s;};
X x{1, "Hi"}; // Not an initializer_list here.前面已经提到,对于带有大括号初始化器的std::pair的初始化,您需要一个构造函数,它接受两个元素,即第一个和第二个元素,而不是一个std::initializer_list<T>。例如,在安装了VS2015的机器上,此构造函数如下所示:
template<class _Other1,
class _Other2,
class = enable_if_t<is_constructible<_Ty1, _Other1>::value
&& is_constructible<_Ty2, _Other2>::value>,
enable_if_t<is_convertible<_Other1, _Ty1>::value
&& is_convertible<_Other2, _Ty2>::value, int> = 0>
constexpr pair(_Other1&& _Val1, _Other2&& _Val2) // -----> Here the constructor takes 2 input params
_NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1>::value
&& is_nothrow_constructible<_Ty2, _Other2>::value))
: first(_STD forward<_Other1>(_Val1)), // ----> initialize the first
second(_STD forward<_Other2>(_Val2)) // ----> initialize the second
{ // construct from moved values
}https://stackoverflow.com/questions/62030516
复制相似问题