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

Section: 22.4.4.2 [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.