The following code compiles and runs :
#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;
}
While this one does not :
#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;
}
The sole difference is that in the first case the ext()
function takes an argument of type initializer_list<pair>
(works) while the other uses initializer_list<tuple>
(does not work). However, cplusplus.com states that
Pairs are a particular case of tuple.
So why does one code work and the other not ?
The error outputted by clang++ in the second case is :
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.
while g++ outputs :
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} } } );
^
cplusplus.com is not a very good site, because it is full of false statement like "Pairs are a particular case of tuple." You could use cppreference
instead. In fact pair is not a particular case of tuple.
It's considered now that tuple
is the better design; pair
is quite a lot older and can't be changed now because of backwards compatibility.
The error message indicates that the difference is that tuple
has an explicit
constructor, but pair
doesn't.
This means you need to mention the class name when constructing a tuple:
ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );
This will be changed in C++17: the constructor of tuple
will be explicit if and only if one of the tuple's types is class type with explicit constructor. gcc 6 already implements this feature. (Credit - Jonathan Wakely). See N4387
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With