foo({1,2})如何为&#34; void foo(pair <int,int>)&#34;

时间:2015-12-10 19:08:11

标签: c++11

std::pair没有构造函数将初始化列表作为参数,但以下代码如何编译?

void foo(std::pair<int,int> pr)
{
}

void foo2(std::tuple<int,int,int> t)
{
}

void bar()
{
    foo({1,2});                               // compile OK
    foo(std::pair<int,int>{1,2});             // compile OK
    foo2(std::tuple<int,int,int>{1,2,3});     // compile OK
    foo2({1,2,3});     // compile error
}

我正在使用clang3.7.0

1 个答案:

答案 0 :(得分:2)

统一初始化不是关于初始化列表。 braced-init-list(用于初始化对象时{}的技术术语)可以调用任何构造函数(尽管它可以仅限于非显式构造函数,具体取决于你用吧)。它更喜欢initializer_list构造函数,但它将调用与其参数列表匹配的任何构造函数。

因此它调用pair构造函数,该构造函数接受适当类型的两个参数。

由于我上面提到的原因,

foo2是一个编译错误。采用两个值的pair构造函数不是显式的,但tuple的等效构造函数是显式的。因此,您需要显式使用类型名称来调用构造函数:

foo2(std::tuple<int, int, int>{1,2,3});

请注意,在C ++ 17中,如果类型列表中的类型可以非显式地从给定类型转换,则此tuple构造函数将变为非显式。因此,您的原始语句应该在C ++ 17实现下工作。