以下代码编译并运行:
#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;
}
虽然这个没有:
#include <initializer_list>
#include <iostream>
#include <vector>
#include <tuple>
void ext( std::initializer_list<std::tuple<double, std::vector<double> >> myList )
{
//Do something
}
///////////////////////////////////////////////////////////
int main(void) {
ext( { {1.0, {2.0, 3.0, 4.0} } } );
return 0;
}
唯一的区别是,在第一种情况下,ext()
函数采用类型initializer_list<pair>
(有效)的参数,而另一种使用initializer_list<tuple>
(不起作用)。但是,cplusplus.com states that
对是元组的一个特例。
那么为什么一个代码有效而另一个代码没有呢?
第二种情况下clang ++输出的错误是:
main.cpp:33:2: error: no matching function for call to 'ext'
ext( { {1.0, {2.0, 3.0, 4.0} } } );
^~~
main.cpp:7:6: note: candidate function not viable: cannot convert initializer list argument to 'std::tuple<double,
std::vector<double, std::allocator<double> > >'
void ext( std::initializer_list<std::tuple<double, std::vector<double> >> myList )
^
1 error generated.
而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} } } );
^
答案 0 :(得分:15)
cplusplus.com不是一个非常好的网站,因为它充满了虚假陈述,如“对是一个特殊的元组案例”。您可以使用cppreference
代替。事实上,对不是元组的特例。
现在考虑tuple
是更好的设计;由于向后兼容性,pair
已经相当老了,现在无法更改。
错误消息表明不同之处在于tuple
具有explicit
构造函数,但pair
没有。{/ p>
这意味着在构造元组时需要提及类名:
ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );
这将在C ++ 17中进行更改:tuple
的构造函数将是显式的,当且仅当其中一个元组的类型是具有显式构造函数的类类型时。 gcc 6已经实现了这个功能。 (信用 - 乔纳森威克利)。见N4387