c++ - Returning a tuple from a function using uniform initialization
syntax
itemprop="text">
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 href="http://llvm.org/bugs/show_bug.cgi?id=15299">http://llvm.org/bugs/show_bug.cgi?id=15299
and also answer by Howard Hinnant below.
class="post-text" itemprop="text">
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;
}
href="http://en.cppreference.com/w/cpp/utility/tuple/tuple">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 double> 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