Saturday 8 June 2019

c++ - Returning a tuple from a function using uniform initialization syntax




The following code compiles with clang (libc++) and fails with gcc (libstdc++). Why does gcc (libstdc++) complains about an initializer list? I thought the return argument was using uniform initialization syntax.



std::tuple dummy() {
return {2.0, 3.0};
}

int main() {
std::tuple a = dummy();
return 0;

}



Error: line 22: converting to ‘std::tuple’ from initializer \
list would use explicit constructor ‘constexpr std::tuple<_T1, _T2>::tuple(_U1&\
&, _U2&&) [with _U1 = double; _U2 = double; = void; _T\
1 = double; _T2 = double]’





Note: GCC (libstdc++) (and clang (libc++)) accept



std::tuple dummy {1.0, 2.0};


Isn't it the same case?



Update: this is a libc++ extension, see http://llvm.org/bugs/show_bug.cgi?id=15299 and also answer by Howard Hinnant below.


Answer



Unlike for pair<>, implicit construction of a tuple<> is not possible unfortunately. You have to use make_tuple():




#include 

std::tuple dummy()
{
return std::make_tuple(2.0, 3.0); // OK
}

int main()
{

std::tuple a = dummy();
return 0;
}


std::tuple has a variadic constructor, but it is marked as explicit. Thus, it cannot be used in this situation, where a temporary must be implicitly constructible. Per Paragraph 20.4.2 of the C++11 Standard:



namespace std {
template
class tuple {

public:

[...]
explicit tuple(const Types&...); // Marked as explicit!

template
explicit tuple(UTypes&&...); // Marked as explicit!


For the same reason it is illegal to use copy-initialization syntax for initializing tuples:




std::tuple a = {1.0, 2.0}; // ERROR!
std::tuple a{1.0, 2.0}; // OK


Or to construct a tuple implicitly when passing it as an argument to a function:



void f(std::tuple t) { ... }
...
f({1.0, 2.0}); // ERROR!

f(make_tuple(1.0, 2.0)); // OK


Accordingly, if you construct your std::tuple explicitly when returning it in dummy(), no compilation error will occur:



#include 

std::tuple dummy()
{
return std::tuple{2.0, 3.0}; // OK

}

int main()
{
std::tuple a = dummy();
return 0;
}

No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...