Discussion:
[std-proposals] Why no UDL templates on strings?
Matthew Woehlke
2018-11-30 19:58:54 UTC
Permalink
(Apologies if this double-posts; I accidentally sent via gmane
originally, and posting that way is still problematic.)

Why can I not define a template UDL:

// Option 1
template <typename T, T... data>
inline Foo operator""_foo() { ... }

// Option 2
template <char... data
inline Foo operator""_foo() { ... }

...on a string?

"Hello, world!"_foo;
u"Hello, world!"_foo;

This seems like an asinine restriction, especially as at least GCC
already knows how to invoke the UDL:

foo.cpp: error: no matching function for call to
‘operator""_foo<char, 'H', 'e', 'l', 'l', 'o', ' ',
'w', 'o', 'r', 'l', 'd', '!'>()’

The only reason there is 'no matching function' is because the compiler
was not allowed to accept the UDL definition(s) as illustrated above:

foo.cpp: error: literal operator template
‘Foo operator""_foo()’ has invalid parameter list.
Expected non-type template argument pack <char...>

In fact, it's even worse; if I put e.g. a static_assert in the UDL body,
I can see that GCC is even *instantiating* the UDL as expected!

This is a stupid, pointless restriction. I propose we get rid of it.
Thoughts?
--
Matthew
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1b65b95c-c3a7-9281-6af5-387e86765631%40gmail.com.
'Giuseppe D'Angelo' via ISO C++ Standard - Future Proposals
2018-11-30 23:34:37 UTC
Permalink
Hi,
Post by Matthew Woehlke
This is a stupid, pointless restriction. I propose we get rid of it.
Thoughts?
Did you have a look at P0424R1 ?

Cheers,
--
Giuseppe D'Angelo | ***@kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1a7c4340-9c38-4c3d-63ef-4a8cf75a9f99%40kdab.com.
Matthew Woehlke
2018-12-04 21:15:04 UTC
Permalink
On 30/11/2018 18.34, 'Giuseppe D'Angelo' via ISO C++ Standard - Future
Post by 'Giuseppe D'Angelo' via ISO C++ Standard - Future Proposals
Post by Matthew Woehlke
This is a stupid, pointless restriction. I propose we get rid of it.
Thoughts?
Did you have a look at P0424R1 ?
Thanks... I believe I'd seen that previously, but wasn't thinking about
it. However, while it does potentially solve the problem, and arguably
for a larger range of use cases, the syntax I presented:

template <typename T, T... str>
Foo operator"" _foo() { ... }

...is *already supported* by GCC and clang¹. (It's also arguably better,
in that a) it is more consistent with the existing literal operator
templates, and b) having the string as a parameter pack is potentially
more convenient, e.g. you can do `sizeof...(str)` on it.

I feel like this approach should at least be considered. Unless there is
a strong reason to do otherwise, I think it makes sense to standardize
existing practice.

(¹ demo: https://godbolt.org/z/4ynlCY)
--
Matthew
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3c747ed6-9bb9-95df-1d9c-3c5d0336b25d%40gmail.com.
Ville Voutilainen
2018-12-04 21:28:09 UTC
Permalink
Post by Matthew Woehlke
Post by 'Giuseppe D'Angelo' via ISO C++ Standard - Future Proposals
Did you have a look at P0424R1 ?
Thanks... I believe I'd seen that previously, but wasn't thinking about
it. However, while it does potentially solve the problem, and arguably
template <typename T, T... str>
Foo operator"" _foo() { ... }
...is *already supported* by GCC and clang¹. (It's also arguably better,
in that a) it is more consistent with the existing literal operator
templates, and b) having the string as a parameter pack is potentially
more convenient, e.g. you can do `sizeof...(str)` on it.
I feel like this approach should at least be considered. Unless there is
It has been considered. P0424 is following Evolution's guidance.
Post by Matthew Woehlke
a strong reason to do otherwise, I think it makes sense to standardize
Sure there is; representing a compile-time string as individual
characters as template
arguments is a hideously inefficient way to get compile-time strings.
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbQNb1ZNWQ%3DSao%2BO_YxLtN00o2o-_aUX8kiS16swcYcUw%40mail.gmail.com.
i***@gmail.com
2018-12-05 20:29:17 UTC
Permalink
Post by Ville Voutilainen
Post by Matthew Woehlke
Post by 'Giuseppe D'Angelo' via ISO C++ Standard - Future Proposals
Did you have a look at P0424R1 ?
Thanks... I believe I'd seen that previously, but wasn't thinking about
it. However, while it does potentially solve the problem, and arguably
template <typename T, T... str>
Foo operator"" _foo() { ... }
...is *already supported* by GCC and clang¹. (It's also arguably better,
in that a) it is more consistent with the existing literal operator
templates, and b) having the string as a parameter pack is potentially
more convenient, e.g. you can do `sizeof...(str)` on it.
I feel like this approach should at least be considered. Unless there is
It has been considered. P0424 is following Evolution's guidance.
Post by Matthew Woehlke
a strong reason to do otherwise, I think it makes sense to standardize
Sure there is; representing a compile-time string as individual
characters as template
arguments is a hideously inefficient way to get compile-time strings.
If this solution is so bad why GCC and Clang implemented this?
As starting point of some metaprogam list of chars would be preferred.
If you try throw 1000 char long string this will break but for 10-20 range
this could work fine.
This is same domain as (and probably will share implementation):
template <char...> double operator "" _x();
Any other pitfalls that could affect it?
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d6032e3a-fee2-4f69-9e48-9a9b28a8ee11%40isocpp.org.
Ville Voutilainen
2018-12-05 20:37:12 UTC
Permalink
Post by i***@gmail.com
Post by Ville Voutilainen
Sure there is; representing a compile-time string as individual
characters as template
arguments is a hideously inefficient way to get compile-time strings.
If this solution is so bad why GCC and Clang implemented this?
There are compilers designed to be embedded as tools that provide an
accurate representation
of a C++ program/source file for tools above them. The overhead they
suffer from representing
a string literal as a bag of individual single-char template arguments
is infeasible.
Post by i***@gmail.com
As starting point of some metaprogam list of chars would be preferred.
If you try throw 1000 char long string this will break but for 10-20 range this could work fine.
template <char...> double operator "" _x();
Any other pitfalls that could affect it?
We are not in the business of shipping a language where a language
facility breaks down horribly
at a kilobyte limit. Instead of insisting on getting a pack of
characters as a template argument
in order to apply sizeof...(pack) on it, you can just as well do

constexpr std::string real_cpp_code_in_cpp20{My_Arg};
now_use_that_stuff<real_cpp_code_in_cpp20.size()>(whatever);

Would you think that's superior to applying a sizeof... on something
that looks like a pack of chars?
Or otherwise superior to trying to fiddle with raw arrays?
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUa9RE8GEQS3XcPu4U1wxCYmtrgFAbk6H9q%2BQQbF4%2BEFdg%40mail.gmail.com.
i***@gmail.com
2018-12-05 21:42:39 UTC
Permalink
Post by Ville Voutilainen
Post by i***@gmail.com
Post by Ville Voutilainen
Sure there is; representing a compile-time string as individual
characters as template
arguments is a hideously inefficient way to get compile-time strings.
If this solution is so bad why GCC and Clang implemented this?
There are compilers designed to be embedded as tools that provide an
accurate representation
of a C++ program/source file for tools above them. The overhead they
suffer from representing
a string literal as a bag of individual single-char template arguments
is infeasible.
Post by i***@gmail.com
As starting point of some metaprogam list of chars would be preferred.
If you try throw 1000 char long string this will break but for 10-20
range this could work fine.
Post by i***@gmail.com
template <char...> double operator "" _x();
Any other pitfalls that could affect it?
We are not in the business of shipping a language where a language
facility breaks down horribly
at a kilobyte limit. Instead of insisting on getting a pack of
characters as a template argument
in order to apply sizeof...(pack) on it, you can just as well do
constexpr std::string real_cpp_code_in_cpp20{My_Arg};
now_use_that_stuff<real_cpp_code_in_cpp20.size()>(whatever);
Would you think that's superior to applying a sizeof... on something
that looks like a pack of chars?
Or otherwise superior to trying to fiddle with raw arrays?
In my case use of `sizeof...` is not main part of reason why I want use
this shape of UDL.

I have in mind something like that (compile parser of some syntax in
string):

template<typename>
struct magic_A{};
template<typename, typename>
struct magic_B{};

template<char... A>
struct impl_magic;

template<char... A>
using impl_magic_t = typename impl_magic<A...>::type;

// final case
template<>
struct impl_magic<>
{
using type = void;
};

// "A" is some kind of warper
template<char... A>
struct impl_magic<'A', A...>
{
using type = magic_A<impl_magic_t<A...>>;
};

// "BX" seperate next X chars
template<char A1, char... A>
struct impl_magic<'B', '1', A1, A...>
{
using type = magic_B<impl_magic_t<A1>, impl_magic_t<A...>>;
};
template<char A1, char A2, char... A>
struct impl_magic<'B', '2', A1, A2, A...>
{
using type = magic_B<impl_magic_t<A1, A2>, impl_magic_t<A...>>;
};
template<char A1, char A2, char A3, char... A>
struct impl_magic<'B', '3', A1, A2, A3, A...>
{
using type = magic_B<impl_magic_t<A1, A2, A3>, impl_magic_t<A...>>;
};
//etc. for 4,5, ...

template<typename TChar, TChar... A>
impl_magic_t<A...> operator ""_magic() { return {}; }


decltype("B2AAAA"_magic) z = 1;
//error: conversion from 'int' to non-scalar type 'impl_magic_t<'B', '2',
'A', 'A', 'A', 'A'>'
// {aka 'magic_B<magic_A<magic_A<void> >, magic_A<magic_A<void> > >'}
requested


And now is very easy to use `A...` and I can start string transformations,
with other syntax this is possible too but need more boilerplate to make it
work.
(This code work fine in GCC and Clang)
--
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+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f7dc2a65-811d-4f24-af87-4d5a06773694%40isocpp.org.
Loading...