This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 2419. Clang's libc++ extension to `std::tuple`

Section: 22.4.4.1 [tuple.cnstr] Status: Resolved Submitter: Akim Demaille Opened: 2014-07-11 Last modified: 2018-06-23

Priority: Not Prioritized

View other active issues in [tuple.cnstr].

View all other issues in [tuple.cnstr].

View all issues with Resolved status.

Discussion:

The issue has been submitted after exchanges with the clang++ team as a consequence of two PR I sent:

Issue 20174

Issue 20175

The short version is shown in the program below:

>     #include <iostream>
>     #include <tuple>

>     struct base
>     {
>       void out(const std::tuple<char, char>& w) const
>       {
>         std::cerr << "Tuple: " << std::get<0>(w) << std::get<1>(w) << '\n';
>       }
>     };

>     struct decorator
>     {
>       base b_;

>       template <typename... Args>
>       auto
>       out(Args&&... args)
>         -> decltype(b_.out(args...))
>       {
>         return b_.out(args...);
>       }

>       void out(const char& w)
>       {
>         std::cerr << "char: " << w << '\n';
>       }
>     };

>     int main()
>     {
>       decorator d{base{}};
>       char l = 'a';
>       d.out(l);
>     }

This is a stripped down version of a real world case where I wrap objects in decorators. These decorators contributes some functions, and forward all the rest of the API to the wrapped object using perfect forwarding. There can be overloaded names.

Here the inner object provides an

>     out(const std::tuple<char, char>&) -> void

function, and the wrappers, in addition to perfect forwarding, provides

>     out(const char&) -> void

The main function then call `out(l)` where `l` is a `char` lvalue.

With (GCC's) libstdc++ I get the expected result: the `char` overload is run. With (clang++'s) libc++ it is the tuple version which is run.

>     $ g++-mp-4.9 -std=c++11 bar.cc && ./a.out
>     char: a
>     $ clang++-mp-3.5 -std=c++11 bar.cc -Wall && ./a.out
>     Tuple: a

It turns out that this is the result of an extension of `std::tuple` in libc++ where they accept constructors with fewer values that tuple elements.

The purpose of this issue is to ask the standard to forbid that this extension be allowed to participate in overload resolution.

[2014-10-05, Daniel comments]

This issue is closely related to LWG 2312.

[2014-11 Urbana]

Moved to LEWG.

Extensions to `tuple`'s design are initially a question for LEWG.

Proposed resolution:

This was resolved by the adoption of 2312 and 2549.