C++ 为什么“初始值设定项”列表<;配对>;`和“初始值设定项列表”<;元组>;`表现不同?

C++ 为什么“初始值设定项”列表<;配对>;`和“初始值设定项列表”<;元组>;`表现不同?,c++,tuples,initializer-list,std-pair,C++,Tuples,Initializer List,Std Pair,编译并运行以下代码: #include <initializer_list> #include <iostream> #include <vector> #include <tuple> void ext( std::initializer_list<std::pair<double, std::vector<double> >> myList ) { //Do something } ///////

编译并运行以下代码:

#include <initializer_list>
#include <iostream>
#include <vector>
#include <tuple>

void ext( std::initializer_list<std::pair<double, std::vector<double> >> myList )
{
    //Do something
}

///////////////////////////////////////////////////////////

int main(void) {
    ext( { {1.0, {2.0, 3.0, 4.0} } } );
    return 0;
}
而g++输出:

main.cpp: In function ‘int main()’:
main.cpp:33:35: error: converting to ‘std::tuple<double, std::vector<double, std::allocator<double> > >’ from initializer list would use explicit constructor ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = double; _T2 = std::vector<double>]’
  ext( { {1.0, {2.0, 3.0, 4.0} } } );
                                   ^
main.cpp:在函数“int main()”中:
main.cpp:33:35:错误:从初始值设定项列表转换为“std::tuple”将使用显式构造函数“constexpr std::tuple::tuple(const _T1&,const _T2&)[带_T1=double;_T2=std::vector]”
ext({1.0,{2.0,3.0,4.0}});
^

cplusplus.com不是一个很好的网站,因为它充满了错误的语句,比如“Pairs是tuple的特例”。你可以使用
cppreference
。事实上,pair并不是tuple的特例

现在认为
tuple
是更好的设计<代码>对比较旧,由于向后兼容,现在无法更改

错误消息表明不同之处在于
tuple
有一个
显式的
构造函数,但
pair
没有

这意味着您在构造元组时需要提及类名:

 ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );
ext({std::tuple{1.0,{2.0,3.0,4.0}});


这将在C++17中更改:
tuple
的构造函数将是显式的,当且仅当tuple的类型之一是具有显式构造函数的类类型时。GCC6已经实现了这个特性。(信贷——乔纳森·韦克利)。请参见

N.B.
元组构造函数的显式
-ness现在取决于参数类型,示例代码将在C++17中有效(今天使用GCC 6编译)。@JonathanWakely感谢您提供的信息。我只是想知道,如果OP问我“为什么它是明确的,这似乎很烦人”,而我没有任何好的回答,我会怎么回答answer@M.M谢谢你的帮助!事实上,这将是一个好问题…
main.cpp: In function ‘int main()’:
main.cpp:33:35: error: converting to ‘std::tuple<double, std::vector<double, std::allocator<double> > >’ from initializer list would use explicit constructor ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = double; _T2 = std::vector<double>]’
  ext( { {1.0, {2.0, 3.0, 4.0} } } );
                                   ^
 ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );