220 35841 <28330aa0-547c-c2d9-f45d-f364b4fe48ce@wanadoo.fr> article
Path: news.gmane.org!.POSTED!not-for-mail
From: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Output parameters
Date: Sun, 10 Dec 2017 06:49:55 +0100
Lines: 543
Approved: news@gmane.org
Message-ID: <28330aa0-547c-c2d9-f45d-f364b4fe48ce@wanadoo.fr>
References: <1c1bb50b-2d59-4247-a158-158065fb1a9a@isocpp.org>
 <0c471d5c-b9b2-40f9-a2bf-908edbb1f272@isocpp.org>
 <17e3b13c-eb1b-fc2c-590e-3d394f164f9a@wanadoo.fr>
 <d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="------------601F283FFD07C34AD6DB34DB"
X-Trace: blaine.gmane.org 1512884997 12690 195.159.176.226 (10 Dec 2017 05:49:57 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 10 Dec 2017 05:49:57 +0000 (UTC)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0)
 Gecko/20100101 Thunderbird/52.5.0
Cc: jmckesson@gmail.com
To: std-proposals@isocpp.org, odomobo@gmail.com
Original-X-From: std-proposals+bncBDH67CONY4PBBBUWWPIQKGQECSLELWA@isocpp.org Sun Dec 10 06:49:52 2017
Return-path: <std-proposals+bncBDH67CONY4PBBBUWWPIQKGQECSLELWA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-wm0-f71.google.com ([74.125.82.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDH67CONY4PBBBUWWPIQKGQECSLELWA@isocpp.org>)
	id 1eNuUp-000361-Qm
	for gclcip-std-proposals@m.gmane.org; Sun, 10 Dec 2017 06:49:51 +0100
Original-Received: by mail-wm0-f71.google.com with SMTP id v69sf2918256wmd.2
        for <gclcip-std-proposals@m.gmane.org>; Sat, 09 Dec 2017 21:49:59 -0800 (PST)
ARC-Seal: i=2; a=rsa-sha256; t=1512884999; cv=pass;
        d=google.com; s=arc-20160816;
        b=Zc9NXb6Wa3OQEtACwyxLJ5nochEo7vz5eegT6TkgU+4SqBV4ApJVV85NFeyi6xwHJy
         mmpKIsZYx2Jwn4QEFtwsQ9es1N38QfHx9sj1HKdZSbhzzOg4xqo8WoWo1u89fDgBmOzc
         6gOAVmslrUkWDBmGPY1v6DUUu9q0GFDr0XBFfVCog/YQpzhueHPPYwmCMrvlJUvchB0N
         FYgBtsukLyQ39YybV11Q3dsunDqczig5FdOCN4I6ovqkPQ2wKD28Ctm7WhRGRrW0yn7a
         YcJQiSWS8Q5zD6AZUr1kMlqWZ+fmW+KFXPxlepCQJ9GgPf+gFUk1YwZ3RuwjLuIDB6iJ
         ksvw==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:content-language
         :in-reply-to:mime-version:user-agent:date:message-id:from:references
         :cc:to:subject:arc-authentication-results:arc-message-signature
         :dkim-signature:arc-authentication-results;
        bh=AjkRsMvIOkgzYsnLKKneughMEhbSbBkiRin15kRbf78=;
        b=iAopfZTg85Bi16nOvlH8fKEPZKPMAGD73Tz4TY+Q5HtWdI6sA0rjvc66I6DBzZr7bl
         JtKlVy5yIP+gQpCYL9PNZrZkIfQ7wB7YC07YomOb25Kpbt3ltAj4QTj6LllY7zzE6zXY
         axJZBTzOfgBXGnHFjiNXdtTAq7Rn7Cv4xzLrUy/cQW5TEM+JtsAP9YrjPK/afJ1BnBV2
         xY7PS6Bd/crHu11HIpUzMh9PzNmhuHEC+TvnOAKkLAVTUSG4pz3ycbasylrWsJj6EHRI
         V8TEEyRpT0vFYmHsfjOUMoYnfhdjzKb/MFs+ilqpehmLf0mZ/WqB1qG84XIt7Z7InhAx
         bIqA==
ARC-Authentication-Results: i=2; mx.google.com;
       spf=neutral (google.com: 80.12.242.132 is neither permitted nor denied by best guess record for domain of vicente.botet@wanadoo.fr) smtp.mailfrom=vicente.botet@wanadoo.fr
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=subject:to:cc:references:from:message-id:date:user-agent
         :mime-version:in-reply-to:content-language:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=AjkRsMvIOkgzYsnLKKneughMEhbSbBkiRin15kRbf78=;
        b=mgJ0Fewzv/giRYMzLYSgbpPXY38g0EziADA+oJjglFNHUknjhPLQSRZKOuI2AqtACd
         sEIh7KkQW801gak188o7RlrX3Mk1aiRSkvJo1Af7Cy/AFZ94pVQqKLFMyDIj++Ezsg7L
         i+SyKMERYLa2Xvp9NuY8pBNrVajkEjTGo9E9Xuuw2eUOBzLZ3Sq0voUhkMJbxHc7OiCU
         fF23dy9txMIDriy0WHBeWXZdc44iAM06yXFK3OdLBJjllkK5YAI+D/1PNkA71M1HwIIn
         a/wJGlfO8x//0YXVbKUgt3jYQcxsxJtjUUYh/IyFZNe2HIO4Ls9e8sP0H6fqmDMmvKEe
         jAZQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:subject:to:cc:references:from:message-id:date
         :user-agent:mime-version:in-reply-to:content-language
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=AjkRsMvIOkgzYsnLKKneughMEhbSbBkiRin15kRbf78=;
        b=CSyQ6P+KcCDWLJIR12ABbA3aLbDQX/YXC9Cz8kB3pgbAwEx5eAVijHlXmM9eP+gcJv
         cXZH0mE5yL088Qn7joFqPAvbXVyhhTuwnQT5tc4T+1r9nLUqndpo0HUfxkroqXyqPb5F
         tdp0X2dGeLTHSDxg6+uak0bKFNiSV9chXf/uIMFKhVy2T0uuIpRshhU/4Yn7z/cnE8Yl
         uo7khYelRhOD4jFNvZC7swz9ZYYSyqIMVfBFRK90H5h8MyzTBQVR1Wh1/6RSDrch1z1O
         eXYB0Hv+y4sx1xOGZPWgpaBg26xZD1elyVUCuWs+tvM/xLvNOquYLPLei65rn1Fu8Gao
        
X-Gm-Message-State: AKGB3mJm+wtZlxPeR5UEZy66x4iSetubV9g/AdGLF4b3/WnbpGK+g7Br
	PwQIbhIaOc0vyH/dqSw6URs=
X-Google-Smtp-Source: AGs4zMaAjqZBxg8VnW6yHef01GjNLclSZ9f8El7Gut6PvdyxXm76IUuqoyUTj9BIgDEzq2Wd9eocMQ==
X-Received: by 10.28.135.82 with SMTP id j79mr1014487wmd.7.1512884999209;
        Sat, 09 Dec 2017 21:49:59 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.28.120.3 with SMTP id t3ls949597wmc.5.canary-gmail; Sat, 09
 Dec 2017 21:49:57 -0800 (PST)
X-Received: by 10.223.136.164 with SMTP id f33mr30248133wrf.162.1512884997736;
        Sat, 09 Dec 2017 21:49:57 -0800 (PST)
ARC-Seal: i=1; a=rsa-sha256; t=1512884997; cv=none;
        d=google.com; s=arc-20160816;
        b=PWH97hQWskp657KAaan+jqVAH4dxwqAzKBo9wQuyJ1gdIeq/KpeUz6SSwSBiv+XzAa
         XPz2u1D9qF/V/hjGojQIffNLTaFrqfiZ56F/RmIJ3dRfAmItsCTusk2qn4GY7dHWFWyI
         0qhFvIfj8g4rxSGiq1Zj1TMWeY5kvbjoBh1JwvqjinMm4VG7cfYfNPq4wCxeKxY2dB9W
         QgDIOVKHFpka0oxZ7g8lXrXdV0oNyeOsMwdVhxzsxxDzEvzsUgtNKA8ftgZi+0V91M27
         BsdH6dFVpxKMtNM02Fo8+vwpZg8qTvUfcogb6VzHN+5Oup4N70AOU9Eq6KRGOdcvdXly
         l5OA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=content-language:in-reply-to:mime-version:user-agent:date
         :message-id:from:references:cc:to:subject:arc-authentication-results;
        bh=4o2e75YT0leh/YAHLdIwC8kATA3Mpi+w3aJ6+OWsnD8=;
        b=R0s4ZbEGkBYgz4XEBRZH74ziQiUfj8qknm0mYMJIdl8fIWy56LriS+tX1wpvn7sezS
         dRX41R2jug570bQ+/CVfoiBq7inwXkEayRaLuDuHJVqu/BRSWL6fyv4kk7gZk1th5+f5
         a0fUHhkbeqCWwpYJdWNZr5e1tI0Ix0Ly+f6wvv33ak3gftb1XnB+HkwHCkUYJ60jd08y
         Owoe5XhfI872bCZR+jt00uo6OVxZ/sfa8cdc+u6C6vo+r5WHint/TmHojaLNb8rdU6Mp
         pVxsFTM7XlO0WDOZ+YQte4s9yxhFA9btH81JuoTTBGrCZVpqh2EBVBvU7UwxG2/HKcGp
         b5vQ==
ARC-Authentication-Results: i=1; mx.google.com;
       spf=neutral (google.com: 80.12.242.132 is neither permitted nor denied by best guess record for domain of vicente.botet@wanadoo.fr) smtp.mailfrom=vicente.botet@wanadoo.fr
Original-Received: from smtp.smtpout.orange.fr (smtp10.smtpout.orange.fr. [80.12.242.132])
        by mx.google.com with ESMTPS id 72si3033883wmh.138.2017.12.09.21.49.57
        for <std-proposals@isocpp.org>
        (version=TLS1 cipher=AES128-SHA bits=128/128);
        Sat, 09 Dec 2017 21:49:57 -0800 (PST)
Received-SPF: neutral (google.com: 80.12.242.132 is neither permitted nor denied by best guess record for domain of vicente.botet@wanadoo.fr) client-ip=80.12.242.132;
Original-Received: from imac-de-vicente-botet-escriba.home ([81.53.26.42])
	by mwinf5d20 with ME
	id k5pv1w00R0uWBHd035pwvk; Sun, 10 Dec 2017 06:49:57 +0100
X-ME-Helo: imac-de-vicente-botet-escriba.home
X-ME-Auth: dmljZW50ZS5ib3RldEB3YW5hZG9vLmZy
X-ME-Date: Sun, 10 Dec 2017 06:49:57 +0100
X-ME-IP: 81.53.26.42
In-Reply-To: <d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org>
Content-Language: en-US
X-Original-Sender: vicente.botet@wanadoo.fr
X-Original-Authentication-Results: mx.google.com;       spf=neutral
 (google.com: 80.12.242.132 is neither permitted nor denied by best guess
 record for domain of vicente.botet@wanadoo.fr) smtp.mailfrom=vicente.botet@wanadoo.fr
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: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:35841
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/35841>

This is a multi-part message in MIME format.
--------------601F283FFD07C34AD6DB34DB
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 09/12/2017 =C3=A0 22:38, odomobo@gmail.com a =C3=A9crit=C2=A0:
> I can think of one case where output parameters are arguably a better=20
> choice than returning a struct/tuple: when you're returning multiple=20
> values of the same type, which aren't inherently related to each other.
>
From=20
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f20-for-out-out=
put-values-prefer-return-values-to-output-parameters

If a type is expensive to move (e.g., |array<BigPOD>|), consider=20
allocating it on the free store and return a handle (e.g.,=20
|unique_ptr|), or passing it in a reference to non-|const| target object=20
to fill (to be used as an out-parameter).

Since C++17 copy elision applies in some cases.

Lets see for

|struct Package { // exceptional case: expensive-to-move object char=20
header[16]; char load[2024 - 16]; }; ||If copy elision doesn't applies to f=
ill Package fill(); // Bad: large=20
return value void fill(Package&); // OK|


|Package pkg; fill(pkg) |


and in this case maybe an out parameter is welcome

|void fill(out_param<Package>); // Better?|

|Package pkg;|
||

|fill(out(pkg)) |



If copy elision could apply to fill

|Package fill(); // Ok: copy elision void fill(Package&); // Bad|



> If they're different types, you can use a tuple -- the type parameters=20
> will give you info about what's being returned. If the data is=20
> inherently related, then it arguably deserves its own type.
>
> Consider the following example, though:
>
> Case #1
>
> |
> tuple<int,int,int>calculate_averages(vector<int>values);
> |
>
> Case #2
>
> |
> structaverages_out
> {
> intmean;
> intmedian;
> intmode;
> };
>
> averages_out calculate_averages(vector<int>values);
> |
>
> Case #3
>
> |
> voidcalculate_averages(vector<int>values,int&mean,int&median,int&mode);
> |
>
> Case #4
>
> |
> voidcalculate_averages(vector<int>values,output_parameter<int>mean,output=
_parameter<int>median,output_parameter<int>mode);
> |
>
> Case #1 would be the clear winner, if tuples had named parameters=20
> somehow. As it stands, I'd be hesitant to go this route even if I=20
> documented the return type thoroughly.
Range TS has tagged tuples. Maybe you can consider it.
>
> For case #2, Since the three results aren't really related, it feels=20
> clumsy to have a separate struct which is used only in one function.
>
> Case #3 seems pretty clear that they are supposed to be output=20
> parameters, and whose initial values are not for input. However, this=20
> isn't explicit.
>
> Case #4 seems the least bad to me. Output parameters aren't great, but=20
> the fact that the function definition describe its usage is a big win,=20
> IMO.
>
>
> Note, I think the recommendations given here are good, but I don't=20
> think they apply to the above=20
> example:=C2=A0http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines=
#Rf-out-multi
>
If you are talking of the in-out parameter, I agree.

|istream& operator>>(istream& is, string& s); // much like=20
std::operator>>() |

In this case we are forced by the standard library design.

However, for in-out parameters, sometimes it is better to create an=20
object that contains the in-out parameter and pass the other parameters=20
in a function to this object.

line_reader rd(in_out(cin)); // line_reader contains the string to=20
return by reference each time we call to getline

while (auto [succeed, line] =3D rd.getline(); succeed)
{
 =C2=A0 //use line here
}


> Also note, I thought about it, and I think Jake is right that a=20
> non-const reference is clearly an input/output parameter. A separate=20
> type for this doesn't seem useful to me.
I can live with just a reference. Some people coming from the C world=20
prefer a pointer because the call site is explicit that the parameter is=20
in-out.
If I want to be explicit at the call site, I would use an=20
in_out_param<T> and a in_out function to pass the parameter.
The number of such cases should be rare to merit such cumbersome syntax.

The problem with functions with in-out parameters is that them don't=20
compose well, so having a cumbersome syntax for them, could force to=20
find out a better design. This is like the explicit cast. casts are a=20
signal of a bad design most of the time. Having them explicit could help=20
to identify a possible refactoring.

Vicente


--=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/28330aa0-547c-c2d9-f45d-f364b4fe48ce%40wanadoo.f=
r.

--------------601F283FFD07C34AD6DB34DB
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 09/12/2017 =C3=A0 22:38,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:odomobo@gmail.co=
m">odomobo@gmail.com</a> a =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote type=3D"cite"
      cite=3D"mid:d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org">
      <div dir=3D"ltr">I can think of one case where output parameters are
        arguably a better choice than returning a struct/tuple: when
        you're returning multiple values of the same type, which aren't
        inherently related to each other.
        <div><br>
        </div>
      </div>
    </blockquote>
    From
<a class=3D"moz-txt-link-freetext" href=3D"http://isocpp.github.io/CppCoreG=
uidelines/CppCoreGuidelines#f20-for-out-output-values-prefer-return-values-=
to-output-parameters">http://isocpp.github.io/CppCoreGuidelines/CppCoreGuid=
elines#f20-for-out-output-values-prefer-return-values-to-output-parameters<=
/a><br>
    <br>
    If a type is expensive to move (e.g., <code
      class=3D"highlighter-rouge no-highlight">array&lt;BigPOD&gt;</code>),
    consider allocating it on the free store and return a handle (e.g.,
    <code class=3D"highlighter-rouge no-highlight">unique_ptr</code>), or
    passing it in a reference to non-<code class=3D"highlighter-rouge
      no-highlight">const</code> target object to fill (to be used as an
    out-parameter).<br>
    <br>
    Since C++17 copy elision applies in some cases.<br>
    <br>
    Lets see for<br>
    <br>
    <pre class=3D"highlight"><code class=3D"no-highlight">struct Package { =
     // exceptional case: expensive-to-move object
    char header[16];
    char load[2024 - 16];
};

</code><code class=3D"no-highlight">If copy elision doesn't applies to fill

Package fill();       // Bad: large return value
void fill(Package&amp;);  // OK</code></pre>
    <br>
    <pre class=3D"highlight"><code class=3D"no-highlight">Package pkg;
fill(pkg)
</code></pre>
    <br>
    and in this case maybe an out parameter is welcome<br>
    <br>
    <pre class=3D"highlight"><code class=3D"no-highlight">void fill(out_par=
am&lt;Package&gt;);  // Better?</code></pre>
    <code class=3D"no-highlight">Package pkg;</code><br>
    <code class=3D"no-highlight"></code>
    <pre class=3D"highlight"><code class=3D"no-highlight">fill(out(pkg))
</code></pre>
    <br>
    <br>
    If copy elision could apply to fill <br>
    <pre class=3D"highlight"><code class=3D"no-highlight">Package fill();  =
     // Ok: copy elision
void fill(Package&amp;);  // Bad</code></pre>
    <br>
    <br>
    <blockquote type=3D"cite"
      cite=3D"mid:d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org">
      <div dir=3D"ltr">
        <div>If they're different types, you can use a tuple -- the type
          parameters will give you info about what's being returned. If
          the data is inherently related, then it arguably deserves its
          own type.</div>
        <div><br>
        </div>
        <div>Consider the following example, though:</div>
        <div><br>
        </div>
        <div>Case #1</div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"background-color: rgb(250,
            250, 250); border-color: rgb(187, 187, 187); border-style:
            solid; border-width: 1px; word-wrap: break-word;"><code
              class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify">tuple</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  calculate_averages</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">vector</span><span
                  style=3D"color: #080;" class=3D"styled-by-prettify">&lt;i=
nt&gt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  values</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">);</span></div>
            </code></div>
          <br>
          Case #2<br>
          <br>
        </div>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border-color: rgb(187, 187, 187); border-style: solid;
          border-width: 1px; word-wrap: break-word;"><code
            class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">struct</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                averages_out<br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">{</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                =C2=A0</span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">int</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> mean</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0</span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">int</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> median</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0</span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">int</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> mode</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">};</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
                averages_out calculate_averages</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">vector<=
/span><span
                style=3D"color: #080;" class=3D"styled-by-prettify">&lt;int=
&gt;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> values=
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n></div>
          </code></div>
        <div>
          <div><br>
          </div>
          <div>Case #3</div>
          <div><br>
          </div>
          <div>
            <div class=3D"prettyprint" style=3D"background-color: rgb(250,
              250, 250); border-color: rgb(187, 187, 187); border-style:
              solid; border-width: 1px; word-wrap: break-word;"><code
                class=3D"prettyprint">
                <div class=3D"subprettyprint"><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">void</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    calculate_averages</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">(</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">vec=
tor</span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">&lt=
;int&gt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    values</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    mean</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">in<=
/span><font
                    color=3D"#666600"><span style=3D"color: #008;"
                      class=3D"styled-by-prettify">t</span><span
                      style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;</span><span
                      style=3D"color: #000;" class=3D"styled-by-prettify">
                      median</span><span style=3D"color: #660;"
                      class=3D"styled-by-prettify">,</span><span
                      style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span
                      style=3D"color: #008;" class=3D"styled-by-prettify">i=
nt</span><span
                      style=3D"color: #660;" class=3D"styled-by-prettify">&=
amp;</span><span
                      style=3D"color: #000;" class=3D"styled-by-prettify">
                      mode</span><span style=3D"color: #660;"
                      class=3D"styled-by-prettify">);</span></font></div>
              </code></div>
            <br>
          </div>
          <div>Case #4</div>
          <div><br>
          </div>
          <div>
            <div class=3D"prettyprint" style=3D"background-color: rgb(250,
              250, 250); border-color: rgb(187, 187, 187); border-style:
              solid; border-width: 1px; word-wrap: break-word;"><code
                class=3D"prettyprint">
                <div class=3D"subprettyprint"><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">void</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    calculate_averages</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">(</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">vec=
tor</span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">&lt=
;int&gt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    values</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    output_parameter</span><span style=3D"color: #080;"
                    class=3D"styled-by-prettify">&lt;int&gt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    mean</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    output_parameter</span><span style=3D"color: #080;"
                    class=3D"styled-by-prettify">&lt;int&gt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    median</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">,</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    output_parameter</span><span style=3D"color: #080;"
                    class=3D"styled-by-prettify">&lt;int&gt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    mode</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">);</span></div>
              </code></div>
            <br>
          </div>
          <div>Case #1 would be the clear winner, if tuples had named
            parameters somehow. As it stands, I'd be hesitant to go this
            route even if I documented the return type thoroughly.</div>
        </div>
      </div>
    </blockquote>
    Range TS has tagged tuples. Maybe you can consider it.<br>
    <blockquote type=3D"cite"
      cite=3D"mid:d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org">
      <div dir=3D"ltr">
        <div>
          <div><br>
          </div>
          <div>For case #2, Since the three results aren't really
            related, it feels clumsy to have a separate struct which is
            used only in one function.</div>
          <div><br>
          </div>
          <div>Case #3 seems pretty clear that they are supposed to be
            output parameters, and whose initial values are not for
            input. However, this isn't explicit.</div>
          <div><br>
          </div>
          <div>Case #4 seems the least bad to me. Output parameters
            aren't great, but the fact that the function definition
            describe its usage is a big win, IMO.</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>Note, I think the recommendations given here are good,
            but I don't think they apply to the above
example:=C2=A0<a class=3D"moz-txt-link-freetext" href=3D"http://isocpp.gith=
ub.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out-multi">http://isocpp.githu=
b.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out-multi</a></div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
    If you are talking of the in-out parameter, I agree.<br>
    <br>
    <pre class=3D"highlight"><code class=3D"no-highlight">istream&amp; oper=
ator&gt;&gt;(istream&amp; is, string&amp; s);    // much like std::operator=
&gt;&gt;()

</code></pre>
    In this case we are forced by the standard library design.<br>
    <br>
    However, for in-out parameters, sometimes it is better to create an
    object that contains the in-out parameter and pass the other
    parameters in a function to this object.<br>
    <br>
    line_reader rd(in_out(cin)); // line_reader contains the string to
    return by reference each time we call to getline<br>
    <br>
    while (auto [succeed, line] =3D rd.getline(); succeed)<br>
    { <br>
    =C2=A0 //use line here <br>
    }<br>
    <br>
    <br>
    <blockquote type=3D"cite"
      cite=3D"mid:d750d914-94c4-4f17-b20d-bc8ca51f58ea@isocpp.org">
      <div dir=3D"ltr">
        <div>
          <div>Also note, I thought about it, and I think Jake is right
            that a non-const reference is clearly an input/output
            parameter. A separate type for this doesn't seem useful to
            me.</div>
        </div>
      </div>
    </blockquote>
    I can live with just a reference. Some people coming from the C
    world prefer a pointer because the call site is explicit that the
    parameter is in-out.<br>
    If I want to be explicit at the call site, I would use an
    in_out_param&lt;T&gt; and a in_out function to pass the parameter.<br>
    The number of such cases should be rare to merit such cumbersome
    syntax.<br>
    <br>
    The problem with functions with in-out parameters is that them don't
    compose well, so having a cumbersome syntax for them, could force to
    find out a better design. This is like the explicit cast. casts are
    a signal of a bad design most of the time. Having them explicit
    could help to identify a possible refactoring.<br>
    <br>
    Vicente<br>
    <br>
    <p><br>
    </p>
  </body>
</html>

<p></p>

-- <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 e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/28330aa0-547c-c2d9-f45d-f364b4fe48ce%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/28330aa0-547c-c2d9-f45d-f364b4fe48ce=
%40wanadoo.fr</a>.<br />

--------------601F283FFD07C34AD6DB34DB--

.
