Topic: Comments on string_view: creating a constexpr


Author: jeanmichael.celerier@gmail.com
Date: Sat, 24 Sep 2016 01:59:10 -0700 (PDT)
Raw View
------=_Part_2474_1361963181.1474707550112
Content-Type: multipart/alternative;
 boundary="----=_Part_2475_1575462976.1474707550113"

------=_Part_2475_1575462976.1474707550113
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I found this looking for the same problem.

There is just a minor bug with your implementation of make_literal_array :=
=20
Args should be passed as forwarding reference (is this the official term?)=
=20
else the char[] arrays decays into char*=20
during expansion of the parameter pack, and sizeof(args) will become=20
sizeof(char*) which=20
may more often than not produce unexpected results.

Best,
Jean-Micha=C3=ABl

Le vendredi 12 d=C3=A9cembre 2014 02:17:58 UTC+1, Matthew Fioravante a =C3=
=A9crit :
>
> It is a common idiom to create a global array of string literals at=20
> compile time:
>
> foo.h
> class Foo {
>   enum Color { kRed, kGreen, kBlue };
>   static constexpr const char* const kColorStr[] =3D { "Red", "Green",=20
> "Blue" };
> };
>
> foo.cpp
> constexpr const char* const Foo::kColorStr[];
>
> There are a few problems with this. One is that it uses a C array, which=
=20
> is somewhat clumsy and error prone to use because it doesn't have a size(=
)=20
> member function (error prone sizeof() calculations to iterate using=20
> indices) and it also decays to a pointer. The strings are also represente=
d=20
> by null terminated char* pointers which requires a strlen() call whenever=
=20
> you need the length. The strlen() may be optimized out in somecases, but=
=20
> strlen() isn't constexpr so you cannot get the string length at compile=
=20
> time.
>
> What would be ideal is to have the type of kColorStr be=20
> std::array<string_view,N>. If we had a constexpr make_array() to construc=
t=20
> a std::array from a variable number of objects along with a string view=
=20
> user defined literal (not in the proposal but mentioned as possibility in=
=20
> the future) we could do this:
>
> static constexpr auto kColorStr =3D make_array("Red"sv, "Green"sv, "Blue"=
sv
> );
> //decltype(kColorStr) =3D=3D std::array<string_view, 3>
>
> Using an array<string_view,N> has other advantages, namely that it=20
> automatically converts to an array_view<string_view>. This makes the stri=
ng=20
> table very easy to use in your program. Here is one example.
>
> //Assumes E starts from 0 and is contiguous
> template <typename E>
> std::optional<E> enum_to_str(string_view s, carray_view<string_view> tags=
)=20
> {
>   for(int i =3D 0; i < int(tags.size()); ++i) {
>     if(s =3D=3D tags[i]) {
>       return E(i);
>     }
>   }
>   return {};
> }
>
> assert(enum_to_str<Foo::Color>("Red", Foo::kColorStr) =3D=3D Foo::Red);
>
> A string_view[N] would also work here but const char* [N] or=20
> std::array<const char*, N> would not. We want things to be string_view's =
or=20
> strings and not char*. If the table is based on char*, you have to do a=
=20
> conversion to string_view and construct temporary string_view tables if y=
ou=20
> want to use string_views to interact with the table.
>
> Using a string_view user defined literal "sv" has problems. The biggest=
=20
> being that we have to add a using declaration to enable it. These constex=
pr=20
> string tables will be defined in header files and adding using statements=
=20
> to a header file is never a good idea.
>
> I solved this problem by adding a simple static method to my string_view=
=20
> class:
>
> template <typename... Args>
> constexpr std::array<string_view,sizeof...(Args)> string_view::
> make_literal_array(Args... args) {
>   return std::array<string_view,sizeof...(Args)>(string_view(args, sizeof=
(
> args)-1)...);
> }
>
> This uses the (char*, size_t) constructor because there is no array=20
> constructor (for good reason, see the paper), and the char* constructor=
=20
> calls strlen() which is not constexpr. It also correctly supports string=
=20
> literals with embedded nulls. This function will produce garbage if you=
=20
> don't feed it string literals but we can probably add some static_asserts=
=20
> to catch some of the incorrect usage. The name is obvious enough to not u=
se=20
> it the wrong way.
>
> Example usage:
>
> foo.h
> class Foo {
>   enum Color { kRed, kGreen, kBlue };
>   static constexpr auto kColorStr =3D string_view::make_literal_array("Re=
d",=20
> "Green", "Blue");
> };
>
> foo.cpp
> constexpr decltype(Foo::kColorStr) Foo::kColorStr;
>
> Maybe something like my make_literal_array should be standardized? How=20
> would you create a global constexpr array<string_view,N>?
>
>
>
>

--=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/0a6fbf8f-966e-416e-9430-c22a94ebc84d%40isocpp.or=
g.

------=_Part_2475_1575462976.1474707550113
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I found this looking for the same problem.<br><br>There is=
 just a minor bug with your implementation of <span style=3D"font-family: c=
ourier new,monospace;">make_literal_array</span> : <br><span style=3D"font-=
family: courier new,monospace;">Args</span> should be passed as forwarding =
reference (is this the official term?) else the <span style=3D"font-family:=
 courier new,monospace;">char[] </span>arrays decays into <span style=3D"fo=
nt-family: courier new,monospace;">char*</span> <br>during expansion of the=
 parameter pack, and <span style=3D"font-family: courier new,monospace;">si=
zeof(args) </span>will become <span style=3D"font-family: courier new,monos=
pace;">sizeof(char*)</span> which <br>may more often than not produce unexp=
ected results.<br><br>Best,<br>Jean-Micha=C3=ABl<font size=3D"2"><font size=
=3D"4"><span style=3D"font-family: arial,sans-serif;"><span style=3D"backgr=
ound-color: rgb(250, 250, 250);"><code><font color=3D"#000000"><span style=
=3D"color: rgb(102, 102, 0);"><font color=3D"#000000"><br></font></span></f=
ont></code></span></span></font></font><br>Le vendredi 12 d=C3=A9cembre 201=
4 02:17:58 UTC+1, Matthew Fioravante a =C3=A9crit=C2=A0:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr">It is a common idiom to create=
 a global array of string literals at compile time:<div><br></div><div>foo.=
h</div><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break=
-word;background-color:rgb(250,250,250)"><code><div><span style=3D"color:#0=
08">class</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Foo</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#=
008">enum</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Color</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> kRed</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> kGreen</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> kBlue </span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"><br>=C2=A0 </span><font color=3D"#00=
0088"><span style=3D"color:#008">static</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">constexpr</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">const</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">char</span><span style=3D"color:#660">*<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">const</=
span><span style=3D"color:#000"> kColorStr</span><span style=3D"color:#660"=
>[]</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;Red&q=
uot;</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#080">&quot;Green&quot;</span><span style=3D"col=
or:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
80">&quot;Blue&quot;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">};</span></font><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">};</span></div></code></div><div><br></div>foo.cpp</d=
iv><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-wor=
d;background-color:rgb(250,250,250)"><code><div><font color=3D"#660066"><sp=
an style=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">const</span><span style=3D"color:#000"> </span><=
span style=3D"color:#008">char</span><span style=3D"color:#660">*</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">const</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Foo</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#000">kColorStr</span><sp=
an style=3D"color:#660">[];</span></font></div></code></div><br>There are a=
 few problems with this. One is that it uses a C array, which is somewhat c=
lumsy and error prone to use because it doesn&#39;t have a size() member fu=
nction (error prone sizeof() calculations to iterate using indices) and it =
also decays to a pointer. The strings are also represented by null terminat=
ed char* pointers which requires a strlen() call whenever you need the leng=
th. The strlen() may be optimized out in somecases, but strlen() isn&#39;t =
constexpr so you cannot get the string length at compile time.</div><div><b=
r></div><div>What would be ideal is to have the type of kColorStr be std::a=
rray&lt;string_view,N&gt;. If we had a constexpr make_array() to construct =
a std::array from a variable number of objects along with a string view use=
r defined literal (not in the proposal but mentioned as possibility in the =
future) we could do this:</div><div><span style=3D"font-family:monospace;fo=
nt-size:13.1428575515747px;color:rgb(0,0,0);background-color:rgb(250,250,25=
0)"><br></span><font style=3D"font-family:monospace;font-size:13.1428575515=
747px;background-color:rgb(250,250,250)" color=3D"#000088"><div style=3D"bo=
rder:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(2=
50,250,250)"><code><div><span style=3D"color:#008">static</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> kColorStr </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> make_array</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#080">&quot;Red&quot;</span><span style=3D"color:#00=
0">sv</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
</span><span style=3D"color:#080">&quot;Green&quot;</span><span style=3D"co=
lor:#000">sv</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#080">&quot;Blue&quot;</span><span style=
=3D"color:#000">sv</span><span style=3D"color:#660">);</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#800">//decltype(kColorStr) =
=3D=3D std::array&lt;string_view, 3&gt;</span></div></code></div><span styl=
e=3D"color:rgb(102,102,0)"><br></span></font><span style=3D"font-family:mon=
ospace;font-size:13.1428575515747px;color:rgb(0,0,0);background-color:rgb(2=
50,250,250)">Using an array&lt;string_view,N&gt; has other advantages, name=
ly that it automatically converts to an array_view&lt;string_view&gt;. This=
 makes the string table very easy to use in your program. Here is one examp=
le.</span></div><div><span style=3D"font-family:monospace;font-size:13.1428=
575515747px;color:rgb(0,0,0);background-color:rgb(250,250,250)"><br></span>=
</div><div><span style=3D"font-family:monospace;font-size:13.1428575515747p=
x;background-color:rgb(250,250,250)"><div style=3D"border:1px solid rgb(187=
,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><di=
v><span style=3D"color:#800">//Assumes E starts from 0 and is contiguous</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">typename</span><span style=3D"color:#000"=
> E</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
<br>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">optional</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#000">E</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> enum_to_str</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">string_view s</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> carray_view</span><span style=3D"color:#080">&lt;string_=
view&gt;</span><span style=3D"color:#000"> tags</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:=
#008">for</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">int</span><span style=3D"color:#000"> i </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0=
</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> i </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">int</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">tags</span><span style=3D"color:#660">.</span><sp=
an style=3D"color:#000">size</span><span style=3D"color:#660">());</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">++</span><span =
style=3D"color:#000">i</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">s </span><span s=
tyle=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> tags</span><sp=
an style=3D"color:#660">[</span><span style=3D"color:#000">i</span><span st=
yle=3D"color:#660">])</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 </span><span style=3D"color:#008">return</span><span style=3D"color:#000">=
 E</span><span style=3D"color:#660">(</span><span style=3D"color:#000">i</s=
pan><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br>=C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br>=C2=A0 </span><span style=3D"color:#008">return</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{};</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">assert</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">enum_to_str</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Foo</span=
><span style=3D"color:#660">::</span><span style=3D"color:#606">Color</span=
><span style=3D"color:#660">&gt;<wbr>(</span><span style=3D"color:#080">&qu=
ot;Red&quot;</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#606">Foo</span><span style=3D"color:#66=
0">::</span><font color=3D"#660066"><span style=3D"color:#000">kColorStr</s=
pan><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><=
span style=3D"color:#606">Foo</span><span style=3D"color:#660">::</span><sp=
an style=3D"color:#606">Red</span><span style=3D"color:#660">);</span></fon=
t></div></code></div><br>A string_view[N] would also work here but const ch=
ar* [N] or std::array&lt;const char*, N&gt; would not. We want things to be=
 string_view&#39;s or strings and not char*. If the table is based on char*=
, you have to do a conversion to string_view and construct temporary string=
_view tables if you want to use string_views to interact with the table.</s=
pan></div><div><span style=3D"font-family:monospace;font-size:13.1428575515=
747px;background-color:rgb(250,250,250)"><br></span></div><div><span style=
=3D"font-family:monospace;font-size:13.1428575515747px;background-color:rgb=
(250,250,250)">Using a string_view user defined literal &quot;sv&quot; has =
problems. The biggest being that we have to add a using declaration to enab=
le it. These constexpr string tables will be defined in header files and ad=
ding using statements to a header file is never a good idea.</span></div><d=
iv><span style=3D"font-family:monospace;font-size:13.1428575515747px;backgr=
ound-color:rgb(250,250,250)"><br></span></div><div><span style=3D"font-fami=
ly:monospace;font-size:13.1428575515747px;background-color:rgb(250,250,250)=
">I solved this problem by adding a simple static method to my string_view =
class:</span></div><div><span style=3D"font-family:monospace;font-size:13.1=
428575515747px;background-color:rgb(250,250,250)"><br></span></div><div><sp=
an style=3D"font-family:monospace;font-size:13.1428575515747px;background-c=
olor:rgb(250,250,250)"><div style=3D"border:1px solid rgb(187,187,187);word=
-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span style=
=3D"color:#008">template</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><spa=
n style=3D"color:#660">...</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#606">Args</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">constexpr</span>=
<span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">array</span><span style=3D"color:#660">&lt;</span=
><span style=3D"color:#000">string_view</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#008">sizeof</span><span style=3D"color:#660">.<=
wbr>..(</span><span style=3D"color:#606">Args</span><span style=3D"color:#6=
60">)&gt;</span><span style=3D"color:#000"> string_view</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">make_literal_<wbr>array=
</span><span style=3D"color:#660">(</span><span style=3D"color:#606">Args</=
span><span style=3D"color:#660">...</span><span style=3D"color:#000"> args<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 <=
/span><span style=3D"color:#008">return</span><span style=3D"color:#000"> s=
td</span><span style=3D"color:#660">::</span><span style=3D"color:#000">arr=
ay</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">s=
tring_view</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
08">sizeof</span><span style=3D"color:#660">.<wbr>..(</span><span style=3D"=
color:#606">Args</span><span style=3D"color:#660">)&gt;(</span><font color=
=3D"#000000"><span style=3D"color:#000">string_view</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">args</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">sizeof</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
0">args</span><span style=3D"color:#660">)-</span><span style=3D"color:#066=
">1</span><span style=3D"color:#660">)...);</span></font><span style=3D"col=
or:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color=
:#000"><br></span></div></code></div><div><span style=3D"font-family:monosp=
ace;font-size:13.1428575515747px;background-color:rgb(250,250,250)"><br></s=
pan></div><div>This uses the (char*, size_t) constructor because there is n=
o array constructor (for good reason, see the paper), and the char* constru=
ctor calls strlen() which is not constexpr. It also correctly supports stri=
ng literals with embedded nulls. This function will produce garbage if you =
don&#39;t feed it string literals but we can probably add some static_asser=
ts to catch some of the incorrect usage. The name is obvious enough to not =
use it the wrong way.</div><br>Example usage:</span></div><div><span style=
=3D"font-family:monospace;font-size:13.1428575515747px;background-color:rgb=
(250,250,250)"><br></span></div><div><span style=3D"font-family:monospace;f=
ont-size:13.1428575515747px;background-color:rgb(250,250,250)">foo.h</span>=
</div><div><span style=3D"font-family:monospace;font-size:13.1428575515747p=
x;background-color:rgb(250,250,250)"><div style=3D"border:1px solid rgb(187=
,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><di=
v><span style=3D"color:#008">class</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Foo</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </sp=
an><span style=3D"color:#008">enum</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Color</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><font color=3D"#000000"><span style=3D"c=
olor:#000"> kRed</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> kGreen</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> kBlue </span><span style=3D"color:#660">};</span><span style=3D=
"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">static</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">auto</span><sp=
an style=3D"color:#000"> kColorStr </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> string_view</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">make_literal_<wbr>array</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#080">&quot;Red&quot;</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#080">&quot;Green&quot;</span><span style=3D"color:#660">=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&quot=
;Blue&quot;</span><span style=3D"color:#660">);</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#660">};</span></font></div></code></=
div><div><span style=3D"font-family:monospace;font-size:13.1428575515747px;=
background-color:rgb(250,250,250)"><br></span></div>foo.cpp</span></div><di=
v><span style=3D"font-family:monospace;font-size:13.1428575515747px;backgro=
und-color:rgb(250,250,250)"><div style=3D"border:1px solid rgb(187,187,187)=
;word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span s=
tyle=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#606">Foo</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">kColorStr</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"> </span><span style=3D"color:#606">Foo</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">kColorStr</span>=
<span style=3D"color:#660">;</span></div></code></div><div><span style=3D"f=
ont-family:monospace;font-size:13.1428575515747px;background-color:rgb(250,=
250,250)"><br></span></div>Maybe something like my make_literal_array shoul=
d be standardized? How would you create a global constexpr array&lt;string_=
view,N&gt;?<br><br></span><br><br></div></div></blockquote></div>

<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/0a6fbf8f-966e-416e-9430-c22a94ebc84d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0a6fbf8f-966e-416e-9430-c22a94ebc84d=
%40isocpp.org</a>.<br />

------=_Part_2475_1575462976.1474707550113--

------=_Part_2474_1361963181.1474707550112--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Sat, 24 Sep 2016 04:48:10 -0700 (PDT)
Raw View
------=_Part_2541_6927092.1474717690101
Content-Type: multipart/alternative;
 boundary="----=_Part_2542_1330620895.1474717690101"

------=_Part_2542_1330620895.1474717690101
Content-Type: text/plain; charset=UTF-8



On Saturday, September 24, 2016 at 9:59:10 AM UTC+1,
jeanmichae...@gmail.com wrote:
>
> I found this looking for the same problem.
>
> There is just a minor bug with your implementation of make_literal_array
> :
> Args should be passed as forwarding reference (is this the official
> term?) else the char[] arrays decays into char*
> during expansion of the parameter pack, and sizeof(args) will become
> sizeof(char*) which
> may more often than not produce unexpected results.
>
>
Yes you're right, actually passing by const reference is sufficient since
string_views and string literals are always const.

Nowadays I do it with variadic size_t....

template <size_t N>
constexpr string_view sv(const char (&literal)[N]) {
 return string_view(literal, N - 1);
}

template <size_t... N>
constexpr std::array<string_view, sizeof...(N)> sva(
    const char (&... literals)[N]) {
 return {{sv(literals)...}};
}

constexpr auto colors = sva("Red", "Green", "Blue");

I usually add these helpers to every project I start. It would be useful to
have some variant of this in the standard.


--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4ccdf40a-2c48-42dd-98f2-5a7611290016%40isocpp.org.

------=_Part_2542_1330620895.1474717690101
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, September 24, 2016 at 9:59:10 AM UTC+=
1, jeanmichae...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">I found this looking for the same problem.<br><br>There=
 is just a minor bug with your implementation of <span style=3D"font-family=
:courier new,monospace">make_literal_array</span> : <br><span style=3D"font=
-family:courier new,monospace">Args</span> should be passed as forwarding r=
eference (is this the official term?) else the <span style=3D"font-family:c=
ourier new,monospace">char[] </span>arrays decays into <span style=3D"font-=
family:courier new,monospace">char*</span> <br>during expansion of the para=
meter pack, and <span style=3D"font-family:courier new,monospace">sizeof(ar=
gs) </span>will become <span style=3D"font-family:courier new,monospace">si=
zeof(char*)</span> which <br>may more often than not produce unexpected res=
ults.<div dir=3D"ltr"><div><br></div></div></div></blockquote><div><br>Yes =
you&#39;re right, actually passing by const reference is sufficient since s=
tring_views and string literals are always const.<br><br>Nowadays I do it w=
ith variadic size_t....<br><br><pre>template &lt;size_t N&gt;
constexpr string_view sv(const char (&amp;literal)[N]) {
 return string_view(literal, N - 1);
}<br><br>template &lt;size_t... N&gt;
constexpr std::array&lt;string_view, sizeof...(N)&gt; sva(
    const char (&amp;... literals)[N]) {
 return {{sv(literals)...}};
}<br><br></pre>constexpr auto colors =3D sva(&quot;Red&quot;, &quot;Green&q=
uot;, &quot;Blue&quot;);<br><br>I usually add these helpers to every projec=
t I start. It would be useful to have some variant of this in the standard.=
<br><br><br></div></div>

<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/4ccdf40a-2c48-42dd-98f2-5a7611290016%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4ccdf40a-2c48-42dd-98f2-5a7611290016=
%40isocpp.org</a>.<br />

------=_Part_2542_1330620895.1474717690101--

------=_Part_2541_6927092.1474717690101--

.