Bug 55713 - std::tuple<ElementType> incorrectly is convertible to "ElementType" when it is an empty class
Summary: std::tuple<ElementType> incorrectly is convertible to "ElementType" when it i...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.7.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2012-12-16 16:46 UTC by Johannes Schaub
Modified: 2016-01-17 23:54 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-12-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Schaub 2012-12-16 16:46:12 UTC
This code cannot be compiled with libstdc++

struct A {};
void f(A);

struct B { B(std::tuple<A>); };
void f(B);

int main() {
  f(std::make_tuple(A()));
}

GCC shouts

  "error: 'A' is an inaccessible base of 'tuple<A>'"

Libstdc++ should not make "std::tuple<EmptyClass>" derive from the empty class directly.
Comment 1 Andrew Pinski 2012-12-16 17:49:20 UTC
This was done for an optimization. And I think it is allowed by the C++ standard too.
Comment 2 Johannes Schaub 2012-12-16 17:52:14 UTC
(In reply to comment #1)
> This was done for an optimization. And I think it is allowed by the C++
> standard too.

From the feedback I received from Stackoverflow ( http://stackoverflow.com/q/13902910/34509 ) I assumed that this behavior is not permissible. There also appear to be ways to make it not behave that way (see LLVM libc++'s implementation).
Comment 3 Jonathan Wakely 2012-12-16 20:39:51 UTC
What stackoverflow says is not gospel, but I agree this should compile.

The summary is misleading, it's not convertible, because the base class is inaccessible.
Comment 4 Marc Glisse 2012-12-16 22:47:34 UTC
libc++'s implementation has the drawback that a tuple of empty types is not empty (at least with the current ABI).

It seems a shame that sfinae now manages to handle access control cleverly enough to disable overloads but regular code still handles access control as something that is only checked after the fact.