220 7793 <52889070.6030506@gmail.com> article
Path: news.gmane.org!not-for-mail
From: David Krauss <potswa@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: inserting an rvalue (was Adding 'extract' method
 to containers)
Date: Sun, 17 Nov 2013 17:46:24 +0800
Lines: 199
Approved: news@gmane.org
Message-ID: <52889070.6030506@gmail.com>
References: <3211ca1f-9759-481d-a864-097f2bd8746a@isocpp.org> <52884D30.7090409@gmail.com> <CAOUeGfs0sbhPWZkbZHxU7W=gB+OqBr8LqD1LhdaduWRNKjvRWQ@mail.gmail.com> <5288640F.7030001@gmail.com> <CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="------------070008080901030907000702"
X-Trace: ger.gmane.org 1384681593 12212 80.91.229.3 (17 Nov 2013 09:46:33 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 17 Nov 2013 09:46:33 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCW25A7E3QCRB6VAUKKAKGQE5XUNZQI@isocpp.org Sun Nov 17 10:46:38 2013
Return-path: <std-proposals+bncBCW25A7E3QCRB6VAUKKAKGQE5XUNZQI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qc0-f200.google.com ([209.85.216.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCW25A7E3QCRB6VAUKKAKGQE5XUNZQI@isocpp.org>)
	id 1Vhyw7-0006f8-Qi
	for gclcip-std-proposals@m.gmane.org; Sun, 17 Nov 2013 10:46:36 +0100
Original-Received: by mail-qc0-f200.google.com with SMTP id r7sf9773542qcx.11
        for <gclcip-std-proposals@m.gmane.org>; Sun, 17 Nov 2013 01:46:35 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:message-id:date:from:user-agent:mime-version:to
         :subject:references:in-reply-to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=9FauVDAsARZk1KAVf+UZel5sKPTsmMuLKwf73i+MDdc=;
        b=dXuuaPBDsxoQFweCAiR2LbHXZX6uKvmA/KyJyJHEJa2Ie8qj/a6deM6Uh8ICR3+FcG
         hMnZiwAxZLLnfZX9jsE+XBoyjV+iXxdf7uV6nhcBM5k04oDrgNSazXsqd2+OUB0kS2tE
         gg9pHc2wLqhQHgAeWLiZsikDRJo96CmsUaXLha4h6frCrG08+T9ylCtlHq41zxGNLdVh
         em0jLo/aftsR3cSq2qgvElXCWgpmOIzxFqKLsMQJ/nO7B+YJoruc1lBmG1xHf239O6cO
         ufAHhA/6f4YsnbABf0pTLN17AlHFp/f73xUKk15Rz2pATyv562qAD7oYjTEoc/5rMfTw
         9A2g==
X-Gm-Message-State: ALoCoQksB9/NCspikSNIc8jMkqrnMyDyGZEQ5e/SkBlcX3SNpDbh+Z0tnpa6w5olHUAzP3jtR6IN
X-Received: by 10.58.237.10 with SMTP id uy10mr6503421vec.16.1384681594703;
        Sun, 17 Nov 2013 01:46:34 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.117.69 with SMTP id kc5ls2326309qeb.42.gmail; Sun, 17 Nov
 2013 01:46:34 -0800 (PST)
X-Received: by 10.236.101.133 with SMTP id b5mr11827731yhg.16.1384681594089;
        Sun, 17 Nov 2013 01:46:34 -0800 (PST)
Original-Received: from mail-pa0-x234.google.com (mail-pa0-x234.google.com [2607:f8b0:400e:c03::234])
        by mx.google.com with ESMTPS id 8si9115151yhq.143.2013.11.17.01.46.33
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 17 Nov 2013 01:46:34 -0800 (PST)
Received-SPF: pass (google.com: domain of potswa@gmail.com designates 2607:f8b0:400e:c03::234 as permitted sender) client-ip=2607:f8b0:400e:c03::234;
Original-Received: by mail-pa0-f52.google.com with SMTP id ld10so873416pab.25
        for <std-proposals@isocpp.org>; Sun, 17 Nov 2013 01:46:33 -0800 (PST)
X-Received: by 10.68.133.133 with SMTP id pc5mr7756433pbb.131.1384681592930;
        Sun, 17 Nov 2013 01:46:32 -0800 (PST)
Original-Received: from Davids-MacBook-Pro.local ([121.54.54.51])
        by mx.google.com with ESMTPSA id bp5sm15959535pbb.18.2013.11.17.01.46.28
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 17 Nov 2013 01:46:31 -0800 (PST)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20130801 Thunderbird/17.0.8
In-Reply-To: <CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com>
X-Original-Sender: potswa@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of potswa@gmail.com designates 2607:f8b0:400e:c03::234 as permitted
 sender) smtp.mail=potswa@gmail.com;       dkim=pass header.i=@gmail.com;
       dmarc=pass (p=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:7793
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/7793>

This is a multi-part message in MIME format.
--------------070008080901030907000702
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

On 11/17/13 3:29 PM, xavi wrote:
> In some cases that's possible, but as Jared pointed out, for getting a 
> pointer out of std::set it must be a member function, because it's not 
> possible to do it with the current interface.

This is essentially true, but depending how you look there could be a 
loophole. The implementation could actually perform a const_cast in the 
free function without any friendship to the class, because the issue is 
whether the const_cast is well-formed (I'm not sure; it depends on 
placement new semantics) and whether the moved-from value affects the 
remove(iterator) operation (the container must support this). But tying 
the function closer to the class would probably be cleaner specification.

> No they don't. map::insert doesn't move from its argument unless it is
> actually inserted. And neither does set::insert. The following code
>
>      std::set<std::unique_ptr<int>> my_set;
>      int *p=new int;
>      std::unique_ptr<int> a(p);
>      std::unique_ptr<int> b(p);
>      my_set.insert(std::move(a));
>      my_set.insert(std::move(b));
>      std::cout << (bool)a << (bool)b << "\n";
>
> prints again 01, which means that the second insertion doesn't move from
> the object, since it's already there.

Hmm, I get 01 from GCC but 00 from Clang 3.2.

The spec I was referring to turns out to be specific to std::map. From 
23.4.4.4:

> Otherwisex is considered to be an rvalue as it is converted to value_type and 
inserted into the map.

C++ International Standard Converting a tuple or pair of references to 
value_type would already doom the object, but actually this language is 
unspecific as to whether that happens if the insertion doesn't occur.

In the case of std::set there is no spec for insert besides the generic 
Container requirements, and it's an indeterminate moved-from value which 
explains the difference between GCC and Clang.

> And with perfect forwarding it can perform the lookup without copying it.
> I think insert works perfectly well as is now.

Perfect forwarding isn't the problem per se, but that the function needs 
to convert its argument because perfect forwarding disables implicit 
conversion within the caller. That is why the spec says that an rvalue 
argument "is converted to value_type". To be sure when they are the same 
type that does not require an xvalue-to-prvalue move construction, 
neither is that forbidden, and avoiding it would require writing a 
special case.

The other reason this is broken is that such conversions canonically 
occur at the call site. If the conversion were only accessible by the 
caller such as due to friendship, an explicit conversion would be needed 
which is unusual. It's doesn't contravene the Container::insert() 
requirements, though, which are only defined in terms of a value_type 
argument.

I suppose there must be a reason set and map are different here, so I 
have some homework to do before having a really valid complaint.

-- 

--- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--------------070008080901030907000702
Content-Type: text/html; charset=ISO-8859-1

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 11/17/13 3:29 PM, xavi wrote:<br>
    </div>
    <blockquote
cite="mid:CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com"
      type="cite">In some cases that's possible, but as Jared pointed
      out, for getting a
      pointer out of std::set it must be a member function, because it's
      not
      possible to do it with the current interface.</blockquote>
    <br>
    This is essentially true, but depending how you look there could be
    a loophole. The implementation could actually perform a const_cast
    in the free function without any friendship to the class, because
    the issue is whether the const_cast is well-formed (I'm not sure; it
    depends on placement new semantics) and whether the moved-from value
    affects the remove(iterator) operation (the container must support
    this). But tying the function closer to the class would probably be
    cleaner specification.<br>
    <br>
    <blockquote
cite="mid:CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com"
      type="cite">
      <pre wrap="">No they don't. map::insert doesn't move from its argument unless it is
actually inserted. And neither does set::insert. The following code

    std::set&lt;std::unique_ptr&lt;int&gt;&gt; my_set;
    int *p=new int;
    std::unique_ptr&lt;int&gt; a(p);
    std::unique_ptr&lt;int&gt; b(p);
    my_set.insert(std::move(a));
    my_set.insert(std::move(b));
    std::cout &lt;&lt; (bool)a &lt;&lt; (bool)b &lt;&lt; "\n";

prints again 01, which means that the second insertion doesn't move from
the object, since it's already there.</pre>
    </blockquote>
    <br>
    Hmm, I get 01 from GCC but 00 from Clang 3.2.<br>
    <br>
    The spec I was referring to turns out to be specific to std::map.
    From 23.4.4.4:
    <div class="page" title="Page 807">
      <div class="layoutArea">
        <div class="column">
          <p><span style="font-size: 10.000000pt; font-family:
              'LMRoman10'">&gt; Otherwise </span><span
              style="font-size: 10.000000pt; font-family:
              'LMTypewriter10'">x </span><span style="font-size:
              10.000000pt; font-family: 'LMRoman10'">is considered to be
              an rvalue as it is converted to </span><span
              style="font-size: 10.000000pt; font-family:
              'LMTypewriter10'">value_type </span><span
              style="font-size: 10.000000pt; font-family: 'LMRoman10'">and
              inserted into the </span><span style="font-size:
              10.000000pt; font-family: 'LMTypewriter10'">map</span><span
              style="font-size: 10.000000pt; font-family: 'LMRoman10'">.
            </span></p>
        </div>
      </div>
    </div>
    <title>C++ International Standard</title>
    Converting a tuple or pair of references to value_type would already
    doom the object, but actually this language is unspecific as to
    whether that happens if the insertion doesn't occur.<br>
    <br>
    In the case of std::set there is no spec for insert besides the
    generic Container requirements, and it's an indeterminate moved-from
    value which explains the difference between GCC and Clang.<br>
    <br>
    <blockquote
cite="mid:CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com"
      type="cite">
      <pre wrap="">And with perfect forwarding it can perform the lookup without copying it.</pre>
    </blockquote>
    <blockquote
cite="mid:CAOUeGfvwNwt=4M9Yk5xe_uY2GADMuW2YU0vYQXChj763BX_FzQ@mail.gmail.com"
      type="cite">
      <pre wrap="">I think insert works perfectly well as is now.</pre>
    </blockquote>
    <br>
    Perfect forwarding isn't the problem per se, but that the function
    needs to convert its argument because perfect forwarding disables
    implicit conversion within the caller. That is why the spec says
    that an rvalue argument "<span style="font-size: 10.000000pt;
      font-family: 'LMRoman10'">is converted to </span><span
      style="font-size: 10.000000pt; font-family: 'LMTypewriter10'">value_type"</span>.
    To be sure when they are the same type that does not require an
    xvalue-to-prvalue move construction, neither is that forbidden, and
    avoiding it would require writing a special case.<br>
    <br>
    The other reason this is broken is that such conversions canonically
    occur at the call site. If the conversion were only accessible by
    the caller such as due to friendship, an explicit conversion would
    be needed which is unusual. It's doesn't contravene the
    Container::insert() requirements, though, which are only defined in
    terms of a value_type argument.<br>
    <br>
    I suppose there must be a reason set and map are different here, so
    I have some homework to do before having a really valid complaint.<br>
    <br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

--------------070008080901030907000702--

.
