220 8642 <dd04ade3-d7f0-40d6-8af3-20c1a5faa908@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: abolz.lists@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: string_view::is_null()
Date: Thu, 16 Jan 2014 22:59:51 -0800 (PST)
Lines: 366
Approved: news@gmane.org
Message-ID: <dd04ade3-d7f0-40d6-8af3-20c1a5faa908@isocpp.org>
References: <8045a4d2-721d-4725-8bb7-7a91b6f53ec8@isocpp.org>
 <2875722.TjfBuHt6Pp@tjmaciei-mobl2> <CANh-dX=N0DhDbHh5TdaGcc5K5x=qOV6itWJzgVP8aG2facA3RA@mail.gmail.com>
 <2685690.E3vksNc10o@tjmaciei-mobl2>
 <CANh-dXm56n-eaoQB5JaPs9mUi53SJHWAe0h1fmd5AazQQ5Pbcg@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_6962_21373520.1389941991771"
X-Trace: ger.gmane.org 1389941985 14680 80.91.229.3 (17 Jan 2014 06:59:45 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Fri, 17 Jan 2014 06:59:45 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCAJPLFFWYPBB2FJ4OLAKGQE5SZCBLI@isocpp.org Fri Jan 17 07:59:54 2014
Return-path: <std-proposals+bncBCAJPLFFWYPBB2FJ4OLAKGQE5SZCBLI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pb0-f69.google.com ([209.85.160.69])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCAJPLFFWYPBB2FJ4OLAKGQE5SZCBLI@isocpp.org>)
	id 1W43PF-00035B-TO
	for gclcip-std-proposals@m.gmane.org; Fri, 17 Jan 2014 07:59:54 +0100
Original-Received: by mail-pb0-f69.google.com with SMTP id ma3sf8095056pbc.0
        for <gclcip-std-proposals@m.gmane.org>; Thu, 16 Jan 2014 22:59:52 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=DeJVNV5EUS5wb2Mbp7M3QKRu3HfRAGiRY4MDxgwJi1w=;
        b=XRfYAwUe4bwRhK/zJ1852PQc9IwFmf9Qca/sh1lfe77C0p2HhjxoYhnRqGGWFo2iNx
         1crCoWXaJJAk9k8RUsWFoD8zLf7N7ZxcjwhnlpBx5EJJK0xV0w+DawC1ZJT4s1lJo1t8
         robtXsTbNZwsxRAVZB1sInyjqLf9j6s7cwgmmufxEouzlaiD6cWEfzca7YL4FJbKYNUZ
         6VBBq/s4ja1/njOXkSur+1eLQqeUitPya/z/aUnQRA7y7AnW4aaoT/rdkCJefGrkEZEF
         4UOe3hc2sAW8sJ3KFJSDjrGzK7vNNgLVHZl9QcjbM4sdCvStEzDwHGrnZICXsX8s8BXd
         hjBg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=DeJVNV5EUS5wb2Mbp7M3QKRu3HfRAGiRY4MDxgwJi1w=;
        b=HkpDztD6BQ3lKowQGiLq6P4z1aWdofKT1Sf8XAckQA9SC/R+KQ9JtKhwC/LD4itgOJ
         35pAllq2t2voJlTPLRyKvo3vbehKXbV/94/cbPZLHzT4n/AGntoWHRhGfWEIkn576jSi
         4DkQERBz4iOK82Evq8lD5pBBOedpkEJsNLnoSNz+XiidRxCY1BJ/spbZYswfPkxemsCD
         dYSQrSdupQSTuuoRzd6BoZv8Vp9GIfUHhuXT/KLeaMltC8FZHVNFhgdGOokHxHfSU8DX
         mG4p5nAHOY30WsFLzZw3ufXpYG4HIqZ/0tjE8MbBDXFEmnyFQtoOv1pYfv93hBwcLQ76
         ksbw==
X-Gm-Message-State: ALoCoQndF0CcthUIfqRlb4P2QDWMYalPm6MQnTLGw0z+feORSOHVnZ9UDfdeBfr6j74Gfds1P+WG
X-Received: by 10.66.66.196 with SMTP id h4mr113854pat.22.1389941992742;
        Thu, 16 Jan 2014 22:59:52 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.140.80.98 with SMTP id b89ls382941qgd.9.gmail; Thu, 16 Jan
 2014 22:59:52 -0800 (PST)
X-Received: by 10.140.48.8 with SMTP id n8mr6341qga.36.1389941992161;
        Thu, 16 Jan 2014 22:59:52 -0800 (PST)
In-Reply-To: <CANh-dXm56n-eaoQB5JaPs9mUi53SJHWAe0h1fmd5AazQQ5Pbcg@mail.gmail.com>
X-Original-Sender: abolzlists@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:8642
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/8642>

------=_Part_6962_21373520.1389941991771
Content-Type: text/plain; charset=UTF-8

Am Mittwoch, 15. Januar 2014 21:42:20 UTC+1 schrieb Jeffrey Yasskin:
>
> On Wed, Jan 15, 2014 at 11:45 AM, Thiago Macieira <thi...@macieira.org<javascript:>> 
> wrote: 
> > On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin wrote: 
> >> Can you look over some of the uses of isNull() in QT and see what 
> >> fraction are ones where both empty and null are possible values, and 
> >> the distinction is useful rather than just forcing the API to document 
> >> which one is used? 
> > 
> > The far majority of the cases, people just need the empty case. That's 
> what we 
> > recommend. And unless some API in specific documents the distinction, 
> using 
> > isEmpty() is the right thing to do. 
> > 
> > The null option comes in handy when you need to distinguish a field that 
> might 
> > be present but empty from a field that isn't present. QUrl makes use of 
> that 
> > and the equivalent std::networking::uri proposal just uses 
> > std::optional<String> (String is a template). For example: 
> > 
> >         QUrl url1("foo:/"), url2("foo://@/?#"); 
> >         QString query1 = url1.query(), query2 = url2.query(); 
> > 
> > Both query1 and query2 are empty, but only query1 is null, indicating 
> that the 
> > query was not present. The same applies to userInfo(), host(), and 
> fragment(), 
> > and would apply to authority() if the "@" weren't present. 
> > 
> > And you can do: 
> > 
> >         url1.setQuery(""); 
> >         url2.setQuery(QString()); 
> > 
> > to invert the situation. 
> > 
> > The other common case for using nulls is in QVariant and that comes from 
> the 
> > QtSql module: all entries are returned as QVariants and they need to 
> support 
> > database tables that don't contain "NOT NULL" (that is, are nullable). 
> So 
> > QVariant can contain a null int that is different from a zero: 
> > 
> >         QVariant v1, v2{0}; 
> >         v1.convert(QVariant::Int); 
> >         // v1.isNull() == true; v2.isNull() == false 
> > 
> > We don't recommend relying on the nullness of a string. We only condone 
> on the 
> > above cases I described, but I wouldn't be surprised to find more uses. 
> And, 
> > trust me, there's quite a lot of headache involved in keeping the 
> nullness of 
> > certain types across transformations: 
> > 
> >         QString().toUtf8().isNull() == true; 
> >         QString("").toUtf8().isNull() == false; 
> > 
> > And then there are weird questions like: 
> > - does a null QString compare equal to an empty one? (yes) 
> > - does a null QString startsWith() an empty one? Does the opposite? 
> > - same for endsWith(), contains(), indexOf() 
> > - is QString().left(1) null? How about QString().left(0)? 
> > - and what about QString("hello").left(0)? 
> > - if left, right and mid can return null, can leftRef, rightRef and 
> midRef 
> >   (which return QStringRef)? 
> > 
> > I don't know the answer to most of those questions, which means I would 
> > recommend no one rely on a specific behaviour. 
> > 
> > Most of it is unit-tested so we don't break it: 
> > 
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString10startsWithEv 
> > 
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8endsWithEv 
> > 
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv 
> > 
> http://code.woboq.org/qt5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftRefEv 
> > 
> > and what isn't tested I'd feel free to change behaviour at any time. 
>
> Thanks for the detailed discussion of QT's use. I agree there are some 
> times when "not present" is different from "empty", but the fact that 
> in "The far majority of the cases, people just need the empty case" 
> makes me think that the string_view proposal makes the right choice. 
> It's true that this means existing classes like QStringRef can't just 
> become typedefs, but my goal here has been to learn from existing 
> practice so that the standard can avoid making the same mistakes. 
>
> optional<> is always available for cases like SQL and URLs, and using 
> it means that the unusual case is called out rather than hiding inside 
> the same type used for the usual case. 
>
> Thanks again for trying it out, 
> Jeffrey 
>
> P.S. Other people need to make a stronger argument than "sometimes it 
> is convenient". Give concrete examples like Thiago did, or I can't do 
> anything with your email. 
>

Well, I can't make a stronger argument than "convenience" since there is
optional<>, so its always possible to extend string_view with a null value.

In the past I used a string_view-like class to split strings into key-value
pairs. Using the nullness I could easily distinguish "key=" (empty value)
from "key" (null value).
I have also used this for string splitting: A function returning the next
delimiter might return an empty string (an empty delimiter found) or a
null string (no delimiter found).

I just looked into the string_view-like classes mentioned in the proposal
[1,2,3] and the boost implementation [4]. They all allow data() to
return null and pass through the pointer used to construct the string_view.
The original string_ref proposal did exactly the same.

However, N3512 changed this (without mentioning why I think, maybe I
missed something...) and the current proposal states that programmers
used this to signal conditions that differed from empty() and that this was
a source of confusion in interfaces and so is not allowed. Could you
give an example where null-strings resulted in such a confusion? I really
want to avoid making the same mistakes!

Thanks
Alex

[1] 
*https://chromium.googlesource.com/chromium/src/base/+/refs/heads/master/strings/string_piece.h*<https://chromium.googlesource.com/chromium/src/base/+/refs/heads/master/strings/string_piece.h>
[2] *http://llvm.org/docs/doxygen/html/StringRef_8h_source.html*<http://llvm.org/docs/doxygen/html/StringRef_8h_source.html>
[3] 
*https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_stringref.h*<https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_stringref.h>
[4] 
*https://github.com/boostorg/utility/blob/master/include/boost/utility/string_ref.hpp*<https://github.com/boostorg/utility/blob/master/include/boost/utility/string_ref.hpp>

-- 

--- 
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/.

------=_Part_6962_21373520.1389941991771
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Am Mittwoch, 15. Januar 2014 21:42:20 UTC+1 schrieb Jeffre=
y Yasskin:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.=
8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-=
width: 1px; border-left-style: solid;">On Wed, Jan 15, 2014 at 11:45 AM, Th=
iago Macieira &lt;<a onmousedown=3D"this.href=3D'javascript:';return true;"=
 onclick=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" ta=
rget=3D"_blank" gdf-obfuscated-mailto=3D"TwT5x0p7PRYJ">thi...@macieira.org<=
/a>&gt; wrote:
<br>&gt; On quarta-feira, 15 de janeiro de 2014 10:26:14, Jeffrey Yasskin w=
rote:
<br>&gt;&gt; Can you look over some of the uses of isNull() in QT and see w=
hat
<br>&gt;&gt; fraction are ones where both empty and null are possible value=
s, and
<br>&gt;&gt; the distinction is useful rather than just forcing the API to =
document
<br>&gt;&gt; which one is used?
<br>&gt;
<br>&gt; The far majority of the cases, people just need the empty case. Th=
at's what we
<br>&gt; recommend. And unless some API in specific documents the distincti=
on, using
<br>&gt; isEmpty() is the right thing to do.
<br>&gt;
<br>&gt; The null option comes in handy when you need to distinguish a fiel=
d that might
<br>&gt; be present but empty from a field that isn't present. QUrl makes u=
se of that
<br>&gt; and the equivalent std::networking::uri proposal just uses
<br>&gt; std::optional&lt;String&gt; (String is a template). For example:
<br>&gt;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; QUrl url1("foo:/"), url2("foo://@/?#")=
;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; QString query1 =3D url1.query(), query=
2 =3D url2.query();
<br>&gt;
<br>&gt; Both query1 and query2 are empty, but only query1 is null, indicat=
ing that the
<br>&gt; query was not present. The same applies to userInfo(), host(), and=
 fragment(),
<br>&gt; and would apply to authority() if the "@" weren't present.
<br>&gt;
<br>&gt; And you can do:
<br>&gt;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; url1.setQuery("");
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; url2.setQuery(QString());
<br>&gt;
<br>&gt; to invert the situation.
<br>&gt;
<br>&gt; The other common case for using nulls is in QVariant and that come=
s from the
<br>&gt; QtSql module: all entries are returned as QVariants and they need =
to support
<br>&gt; database tables that don't contain "NOT NULL" (that is, are nullab=
le). So
<br>&gt; QVariant can contain a null int that is different from a zero:
<br>&gt;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; QVariant v1, v2{0};
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; v1.convert(QVariant::Int);
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; // v1.isNull() =3D=3D true; v2.isNull(=
) =3D=3D false
<br>&gt;
<br>&gt; We don't recommend relying on the nullness of a string. We only co=
ndone on the
<br>&gt; above cases I described, but I wouldn't be surprised to find more =
uses. And,
<br>&gt; trust me, there's quite a lot of headache involved in keeping the =
nullness of
<br>&gt; certain types across transformations:
<br>&gt;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; QString().toUtf8().isNull() =3D=3D tru=
e;
<br>&gt; &nbsp; &nbsp; &nbsp; &nbsp; QString("").toUtf8().isNull() =3D=3D f=
alse;
<br>&gt;
<br>&gt; And then there are weird questions like:
<br>&gt; - does a null QString compare equal to an empty one? (yes)
<br>&gt; - does a null QString startsWith() an empty one? Does the opposite=
?
<br>&gt; - same for endsWith(), contains(), indexOf()
<br>&gt; - is QString().left(1) null? How about QString().left(0)?
<br>&gt; - and what about QString("hello").left(0)?
<br>&gt; - if left, right and mid can return null, can leftRef, rightRef an=
d midRef
<br>&gt; &nbsp; (which return QStringRef)?
<br>&gt;
<br>&gt; I don't know the answer to most of those questions, which means I =
would
<br>&gt; recommend no one rely on a specific behaviour.
<br>&gt;
<br>&gt; Most of it is unit-tested so we don't break it:
<br>&gt; <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString10startsWithEv\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNH0DkvTqaGjpdgeogyca4zHTXpj9A';return true;" onclick=
=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%=
2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp=
..html%23_ZN11tst_QString10startsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNH=
0DkvTqaGjpdgeogyca4zHTXpj9A';return true;" href=3D"http://code.woboq.org/qt=
5/qtbase/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QSt=
ring10startsWithEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase=
/tests/auto/corelib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<=
wbr>QString10startsWithEv</a>
<br>&gt; <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString8endsWithEv\46sa\75D\46sntz\=
0751\46usg\75AFQjCNEozKVuuIDN2zRdKK2fCefHltxC_Q';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5=
%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html=
%23_ZN11tst_QString8endsWithEv\46sa\75D\46sntz\0751\46usg\75AFQjCNEozKVuuID=
N2zRdKK2fCefHltxC_Q';return true;" href=3D"http://code.woboq.org/qt5/qtbase=
/tests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString8end=
sWithEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto=
/corelib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString=
8endsWithEv</a>
<br>&gt; <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString4leftEv\46sa\75D\46sntz\0751=
\46usg\75AFQjCNF_uztsNplZ08s05SewQrc0SE4bqw';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%2Fq=
tbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%23_=
ZN11tst_QString4leftEv\46sa\75D\46sntz\0751\46usg\75AFQjCNF_uztsNplZ08s05Se=
wQrc0SE4bqw';return true;" href=3D"http://code.woboq.org/qt5/qtbase/tests/a=
uto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString4leftEv" tar=
get=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/corelib/<wb=
r>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_QString4leftEv</a>
<br>&gt; <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcode.woboq.org%2Fqt5%2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqs=
tring%2Ftst_qstring.cpp.html%23_ZN11tst_QString7leftRefEv\46sa\75D\46sntz\0=
751\46usg\75AFQjCNErchfCONblsCTo3UCyQx6cSvRlnA';return true;" onclick=3D"th=
is.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fcode.woboq.org%2Fqt5%=
2Fqtbase%2Ftests%2Fauto%2Fcorelib%2Ftools%2Fqstring%2Ftst_qstring.cpp.html%=
23_ZN11tst_QString7leftRefEv\46sa\75D\46sntz\0751\46usg\75AFQjCNErchfCONbls=
CTo3UCyQx6cSvRlnA';return true;" href=3D"http://code.woboq.org/qt5/qtbase/t=
ests/auto/corelib/tools/qstring/tst_qstring.cpp.html#_ZN11tst_QString7leftR=
efEv" target=3D"_blank">http://code.woboq.org/qt5/<wbr>qtbase/tests/auto/co=
relib/<wbr>tools/qstring/tst_qstring.cpp.<wbr>html#_ZN11tst_<wbr>QString7le=
ftRefEv</a>
<br>&gt;
<br>&gt; and what isn't tested I'd feel free to change behaviour at any tim=
e.
<br>
<br>Thanks for the detailed discussion of QT's use. I agree there are some
<br>times when "not present" is different from "empty", but the fact that
<br>in "The far majority of the cases, people just need the empty case"
<br>makes me think that the string_view proposal makes the right choice.
<br>It's true that this means existing classes like QStringRef can't just
<br>become typedefs, but my goal here has been to learn from existing
<br>practice so that the standard can avoid making the same mistakes.
<br>
<br>optional&lt;&gt; is always available for cases like SQL and URLs, and u=
sing
<br>it means that the unusual case is called out rather than hiding inside
<br>the same type used for the usual case.
<br>
<br>Thanks again for trying it out,
<br>Jeffrey
<br>
<br>P.S. Other people need to make a stronger argument than "sometimes it
<br>is convenient". Give concrete examples like Thiago did, or I can't do
<br>anything with your email.
<br></blockquote><div><br></div><div>Well, I can't make a stronger argument=
 than&nbsp;"convenience" since there is</div><div>optional&lt;&gt;, so its =
always possible to extend string_view with a null value.</div><div><br></di=
v><div>In the past I used a string_view-like&nbsp;class to split strings in=
to key-value</div><div>pairs. Using the nullness I could easily distinguish=
 "key=3D" (empty value)</div><div>from "key" (null value).</div><div>I have=
 also used this for string splitting: A function returning the next</div><d=
iv>delimiter might return an empty string (an empty delimiter found)&nbsp;o=
r a</div><div>null string (no delimiter found).</div><div><br></div><div>I =
just looked into the string_view-like classes mentioned in the proposal</di=
v><div>[1,2,3] and the boost implementation [4]. They all allow data() to</=
div><div>return null and pass through the pointer used to construct the str=
ing_view.</div><div>The original string_ref proposal did exactly the same.<=
/div><div><br></div><div>However, N3512 changed this (without mentioning wh=
y&nbsp;I think, maybe I</div><div>missed something...)&nbsp;and the current=
 proposal states that programmers</div><div>used this to signal conditions =
that differed from empty() and that this was</div><div>a source of confusio=
n in interfaces and so is not allowed. Could you</div><div>give an example =
where null-strings resulted in such a confusion? I really</div><div>want to=
 avoid making the same mistakes!</div><div><br></div><div>Thanks</div><div>=
Alex</div><div><br></div><div>[1] <a href=3D"https://chromium.googlesource.=
com/chromium/src/base/+/refs/heads/master/strings/string_piece.h"><u><font =
color=3D"#0066cc">https://chromium.googlesource.com/chromium/src/base/+/ref=
s/heads/master/strings/string_piece.h</font></u></a></div><div>[2] <a href=
=3D"http://llvm.org/docs/doxygen/html/StringRef_8h_source.html"><u><font co=
lor=3D"#0066cc">http://llvm.org/docs/doxygen/html/StringRef_8h_source.html<=
/font></u></a></div><div>[3] <a href=3D"https://github.com/bloomberg/bde/bl=
ob/master/groups/bsl/bslstl/bslstl_stringref.h"><u><font color=3D"#0066cc">=
https://github.com/bloomberg/bde/blob/master/groups/bsl/bslstl/bslstl_strin=
gref.h</font></u></a></div><div>[4] <a href=3D"https://github.com/boostorg/=
utility/blob/master/include/boost/utility/string_ref.hpp"><u><font color=3D=
"#0066cc">https://github.com/boostorg/utility/blob/master/include/boost/uti=
lity/string_ref.hpp</font></u></a></div></div>

<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 e=
mail 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=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_6962_21373520.1389941991771--

.
