public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/45228]  New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
@ 2010-08-07 20:03 jorrit at jorrit dot de
  2010-08-07 20:25 ` [Bug libstdc++/45228] " jorrit at jorrit dot de
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: jorrit at jorrit dot de @ 2010-08-07 20:03 UTC (permalink / raw)
  To: gcc-bugs

The following program fails to compile:
======================================================================
#include <tuple>

typedef std::tuple<int,int,int> Tuple;
//typedef std::tuple<int,int> Tuple;

      Tuple A() { return Tuple(); }
const Tuple B() { return Tuple(); }

int main()
{
  Tuple test(B());
  //Tuple test(A());
}
======================================================================
The program compiles successfully when A() is used instead of B() to
initialize the "test", or when a two-element tuple is used instead of a
three-element tuple.

This has happened with an svn snapshot of of g++-4.6 (Debians gcc-snapshot
version 20100702-1) and with g++-4.4 (Debians g++-4.4 version 4.4.4-7).

The compiler output is
======================================================================
export PATH=/usr/lib/gcc-snapshot/bin:$PATH && cd
~/src/dune2/dune-pdelab/dune/pdelab/test && g++ --version && g++ --std=c++0x
-O0 -Wall tupletest.cc -o tupletest
g++ (Debian 20100702-1) 4.6.0 20100702 (experimental) [trunk revision 161740]
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In file included from tupletest.cc:1:0:
/usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.6.0/../../../../include/c++/4.6.0/tuple:
In constructor 'std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with
_UHead = const std::tuple<int, int, int>, unsigned int _Idx = 0u, _Head =
int]':
/usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.6.0/../../../../include/c++/4.6.0/tuple:161:38:
  instantiated from 'std::_Tuple_impl<_Idx, _Head, _Tail
...>::_Tuple_impl(_UHead&&, _UTail&& ...) [with _UHead = const std::tuple<int,
int, int>, _UTail = {}, unsigned int _Idx = 0u, _Head = int, _Tail = {int,
int}]'
/usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.6.0/../../../../include/c++/4.6.0/tuple:239:54:
  instantiated from 'std::tuple< <template-parameter-1-1> >::tuple(_UElements&&
...) [with _UElements = {const std::tuple<int, int, int>}, _Elements = {int,
int, int}]'
tupletest.cc:11:17:   instantiated from here
/usr/lib/gcc-snapshot/lib/gcc/i486-linux-gnu/4.6.0/../../../../include/c++/4.6.0/tuple:94:42:
error: cannot convert 'const std::tuple<int, int, int>' to 'int' in
initialization
======================================================================


-- 
           Summary: Can't copy-construct "tuple<int,int,int>" from "const
                    tuple<int,int,int>" rvalue
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jorrit at jorrit dot de
 GCC build triplet: i486-linux-gnu
  GCC host triplet: i486-linux-gnu
GCC target triplet: i486-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
@ 2010-08-07 20:25 ` jorrit at jorrit dot de
  2010-08-07 22:19 ` [Bug libstdc++/45228] [C++0x] " paolo dot carlini at oracle dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jorrit at jorrit dot de @ 2010-08-07 20:25 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from jorrit at jorrit dot de  2010-08-07 20:24 -------
I also reported this to Debian: http://bugs.debian.org/592153


-- 

jorrit at jorrit dot de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jorrit at jorrit dot de


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
  2010-08-07 20:25 ` [Bug libstdc++/45228] " jorrit at jorrit dot de
@ 2010-08-07 22:19 ` paolo dot carlini at oracle dot com
  2010-08-09 13:22 ` jason at redhat dot com
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: paolo dot carlini at oracle dot com @ 2010-08-07 22:19 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from paolo dot carlini at oracle dot com  2010-08-07 22:19 -------
Our std::tuple still needs work, but I see am inconsistency here between the
variadic and the non variadic case which I don't understand, irrespective of
library details.  Consider the following reduced testcase: it outputs *only*
"Two (m)", no "Two (2)". It seems pretty obvious to me that the constructor
"Two", which takes *individual elements*, certainly should never be involved,
but it is, in the variadic case only.

Jason can you have a look? Thanks in advance!

///////////

#include <iostream>

template<typename... Types>
  struct tuple_m
  {
    tuple_m() { }

    explicit
    tuple_m(const Types&...)
    { std::cout << "One (m)\n"; }

    template<typename... UTypes>
      explicit 
      tuple_m(UTypes&&...)
      { std::cout << "Two (m)\n"; }

    tuple_m(const tuple_m&)
    { std::cout << "Three (m)\n"; }

    tuple_m(tuple_m&&)
    { std::cout << "Four (m)\n"; }

    template<typename... UTypes>
      tuple_m(const tuple_m<UTypes...>&)
      { std::cout << "Five (m)\n"; }

    template<typename... UTypes>
      tuple_m(tuple_m<UTypes...>&&)
      { std::cout << "Six (m)\n"; }
  };

template<typename T1, typename T2>
  struct tuple_2
  {
    tuple_2() { }

    explicit
    tuple_2(const T1&, const T2&)
    { std::cout << "One (2)\n"; }

    template<typename UT1, typename UT2>
      explicit
      tuple_2(UT1&&, UT2&&)
      { std::cout << "Two (2)\n"; }

    tuple_2(const tuple_2&)
    { std::cout << "Three (2)\n"; }

    tuple_2(tuple_2&&)
    { std::cout << "Four (2)\n"; }

    template<typename UT1, typename UT2>
      tuple_2(const tuple_2<UT1, UT2>&)
      { std::cout << "Five (2)\n"; }

    template<typename UT1, typename UT2>
      tuple_2(tuple_2<UT1, UT2>&&)
      { std::cout << "Six (2)\n"; }
  };

typedef tuple_2<int, int>       tuple_2_type;
typedef tuple_m<int, int, int>  tuple_m_type;

const tuple_2_type f2() { return tuple_2_type(); }
const tuple_m_type fm() { return tuple_m_type(); }

int main()
{
  tuple_2_type test_2(f2());
  tuple_m_type test_m(fm());
}


-- 

paolo dot carlini at oracle dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |paolo dot carlini at oracle
                   |                            |dot com, jason at gcc dot
                   |                            |gnu dot org
            Summary|Can't copy-construct        |[C++0x] Can't copy-construct
                   |"tuple<int,int,int>" from   |"tuple<int,int,int>" from
                   |"const tuple<int,int,int>"  |"const tuple<int,int,int>"
                   |rvalue                      |rvalue


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
  2010-08-07 20:25 ` [Bug libstdc++/45228] " jorrit at jorrit dot de
  2010-08-07 22:19 ` [Bug libstdc++/45228] [C++0x] " paolo dot carlini at oracle dot com
@ 2010-08-09 13:22 ` jason at redhat dot com
  2010-08-09 13:31 ` paolo dot carlini at oracle dot com
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jason at redhat dot com @ 2010-08-09 13:22 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from jason at redhat dot com  2010-08-09 13:22 -------
Subject: Re:  [C++0x] Can't copy-construct "tuple<int,int,int>"
 from "const tuple<int,int,int>" rvalue

For tuple_m, you have a variadic template constructor that can take 
*any* arguments whatsoever, and will therefore be a better match than 
anything that doesn't have a specific constructor.  In this case, you're 
trying to create a tuple_m from a const tuple_m rvalue, and therefore 
the variadic template is instantiated to form tuple_m(const tuple_m&&), 
which is a better match than either tuple_m(const tuple_m&) or 
tuple_m(tuple_m&&).

For tuple_2, the T&& constructor requires two arguments, so this isn't 
an issue.

This is the same issue that we had with thread; I worked around that for 
the non-const lvalue case by adding thread(thread&) = delete, and you 
could do the same here by adding a const tuple_m&& overload.

But in general, I think any time you have a variadic constructor that 
can take a single T&&, you probably want to use SFINAE to make sure that 
it isn't chosen for a single argument of the enclosing class type.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
                   ` (2 preceding siblings ...)
  2010-08-09 13:22 ` jason at redhat dot com
@ 2010-08-09 13:31 ` paolo dot carlini at oracle dot com
  2010-08-09 13:39 ` jason at redhat dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: paolo dot carlini at oracle dot com @ 2010-08-09 13:31 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from paolo dot carlini at oracle dot com  2010-08-09 13:31 -------
Thanks for the clarification Jason. Indeed, I think the most robust fix is
using SFINAE, and actually we have already quite a bit of language in the FCD
about tuple constuctors vs constraining, I think it's time to look into that in
detail.

I'm also thinking that the weird constructor tuple(tuple<_UElements...>& __in),
which has been suggested at the time by Peter Dimov, falls under the same
reasoning and should be removed, the actual issue sorted out elsewhere again
through SFINAE. If you think differently, just let me know here... Thanks
again.


-- 

paolo dot carlini at oracle dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |paolo dot carlini at oracle
                   |dot org                     |dot com
             Status|UNCONFIRMED                 |ASSIGNED
     Ever Confirmed|0                           |1
   Last reconfirmed|0000-00-00 00:00:00         |2010-08-09 13:31:39
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
                   ` (3 preceding siblings ...)
  2010-08-09 13:31 ` paolo dot carlini at oracle dot com
@ 2010-08-09 13:39 ` jason at redhat dot com
  2010-08-09 13:45 ` paolo dot carlini at oracle dot com
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jason at redhat dot com @ 2010-08-09 13:39 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from jason at redhat dot com  2010-08-09 13:38 -------
Subject: Re:  [C++0x] Can't copy-construct "tuple<int,int,int>"
 from "const tuple<int,int,int>" rvalue

On 08/09/2010 09:31 AM, paolo dot carlini at oracle dot com wrote:
> I'm also thinking that the weird constructor tuple(tuple<_UElements...>&  __in),
> which has been suggested at the time by Peter Dimov, falls under the same
> reasoning and should be removed, the actual issue sorted out elsewhere again
> through SFINAE.

Removed?  To be clear, I was suggesting that you keep the constructor, 
just prevent it from being selected when the deduced parameter type is 
reference-related to the enclosing class.

Jason


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
                   ` (4 preceding siblings ...)
  2010-08-09 13:39 ` jason at redhat dot com
@ 2010-08-09 13:45 ` paolo dot carlini at oracle dot com
  2010-08-10  7:18 ` paolo at gcc dot gnu dot org
  2010-08-10  7:23 ` paolo dot carlini at oracle dot com
  7 siblings, 0 replies; 9+ messages in thread
From: paolo dot carlini at oracle dot com @ 2010-08-09 13:45 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from paolo dot carlini at oracle dot com  2010-08-09 13:44 -------
Note the specific constructor I mentioned:

  // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
  template<typename... _UElements>
    tuple(tuple<_UElements...>& __in)

we are *not* talking there about any of the constructors part of the user
interface, we are talking about a constructor added only for the purpose of
getting right special cases (having to do with cc qualifiers, conversions)
without resorting to SFINAE. I think we should be able to uniformly use *only*
constraining on the user visible constructors, for this issue too. Agreed?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
                   ` (5 preceding siblings ...)
  2010-08-09 13:45 ` paolo dot carlini at oracle dot com
@ 2010-08-10  7:18 ` paolo at gcc dot gnu dot org
  2010-08-10  7:23 ` paolo dot carlini at oracle dot com
  7 siblings, 0 replies; 9+ messages in thread
From: paolo at gcc dot gnu dot org @ 2010-08-10  7:18 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from paolo at gcc dot gnu dot org  2010-08-10 07:18 -------
Subject: Bug 45228

Author: paolo
Date: Tue Aug 10 07:17:44 2010
New Revision: 163049

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163049
Log:
2010-08-10  Paolo Carlini  <paolo.carlini@oracle.com>

        PR libstdc++/45228
        * include/std/tuple (tuple<typename... _Elements>): Constrain
        converting constructors and assignment operators with
        sizeof...(_UElements) == sizeof...(_Elements).
        (tuple(tuple<_UElements...>&): Remove.
        (tuple<typename _T1>): Add.
        * testsuite/20_util/tuple/cons/45228.cc: New.
        * testsuite/20_util/tuple/cons/converting.cc: Likewise.
        * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust
        dg-error line number.

        * include/std/tuple (_Tuple_impl<>::_Tuple_impl(const _Tuple_impl&)):
        Defaulted.

        * include/std/tuple (tuple<typename _T1, typename _T2>
        ::operator=(pair<_U1, _U2>&&)): Use forward.

Added:
    trunk/libstdc++-v3/testsuite/20_util/tuple/cons/45228.cc
    trunk/libstdc++-v3/testsuite/20_util/tuple/cons/converting.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/tuple
    trunk/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug libstdc++/45228] [C++0x] Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue
  2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
                   ` (6 preceding siblings ...)
  2010-08-10  7:18 ` paolo at gcc dot gnu dot org
@ 2010-08-10  7:23 ` paolo dot carlini at oracle dot com
  7 siblings, 0 replies; 9+ messages in thread
From: paolo dot carlini at oracle dot com @ 2010-08-10  7:23 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from paolo dot carlini at oracle dot com  2010-08-10 07:23 -------
Fixed.


-- 

paolo dot carlini at oracle dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|                            |FIXED
   Target Milestone|---                         |4.6.0


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45228


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-08-10  7:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-07 20:03 [Bug libstdc++/45228] New: Can't copy-construct "tuple<int,int,int>" from "const tuple<int,int,int>" rvalue jorrit at jorrit dot de
2010-08-07 20:25 ` [Bug libstdc++/45228] " jorrit at jorrit dot de
2010-08-07 22:19 ` [Bug libstdc++/45228] [C++0x] " paolo dot carlini at oracle dot com
2010-08-09 13:22 ` jason at redhat dot com
2010-08-09 13:31 ` paolo dot carlini at oracle dot com
2010-08-09 13:39 ` jason at redhat dot com
2010-08-09 13:45 ` paolo dot carlini at oracle dot com
2010-08-10  7:18 ` paolo at gcc dot gnu dot org
2010-08-10  7:23 ` paolo dot carlini at oracle dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).