Is there any way to get behavior like this?
// Some definition(s) of operator "" _my_str
// Some definition of function or macro MY_STR_LEN
using T1 = MY_STR_LEN("ape"_my_str);
// T1 is std::integral_constant<std::size_t, 3U>.
using T2 = MY_STR_LEN("aardvark"_my_str);
// T2 is std::integral_constant<std::size_t, 8U>.
It seems not, since the string literals are passed immediately to some_return_type operator "" _my_str(const char*, std::size_t);
and never to a literal operator template (2.14.8/5). That size function parameter can't be used as a template argument, even though it will almost always be a constant expression.
But it seems like there ought to be some way to do this.
Update: The accepted answer, that this is not possible without an extra definition per literal, is accurate for C++11 as asked, and also C++14 and C++17. C++20 allows the exact result asked for:
#include <cstdlib>
#include <type_traits>
#include <string_view>
struct cexpr_str {
const char* ptr;
std::size_t len;
template <std::size_t Len>
constexpr cexpr_str(const char (&str)[Len]) noexcept
: ptr(str), len(Len) {}
};
// Essentially the same as
// std::literals::string_view_literals::operator""sv :
template <cexpr_str Str>
constexpr std::string_view operator "" _my_str () noexcept
{
return std::string_view(Str.ptr, Str.len);
}
#define MY_STR_LEN(sv) \
std::integral_constant<std::size_t, (sv).size()>
A string literal is a sequence of zero or more characters enclosed within single quotation marks. The following are examples of string literals: 'Hello, world!' '10-NOV-91' 'He said, "Take it or leave it."'
A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string. You must always prefix wide-string literals with the letter L.
A literal is a value that is expressed as itself. For example, the number 25 or the string "Hello World" are both literals. A constant is a data type that substitutes a literal. Constants are used when a specific, unchanging value is used various times during the program.
A string literal or anonymous string is a string value in the source code of a computer program. Modern programming languages commonly use a quoted sequence of characters, formally "bracketed delimiters", as in x = "foo" , where "foo" is a string literal with value foo .
Reading C++11 2.14.8 carefully reveals that the "literal operator template" is only considered for numeric literals, but not for string and character literals.
However, the following approach seems to give you constexpr access to the string length (but not the pointer):
struct MyStr
{
char const * str;
unsigned int len;
constexpr MyStr(char const * p, unsigned int n) : str(p), len(n) {}
};
constexpr MyStr operator "" _xyz (char const * s, unsigned int len)
{
return MyStr(s, len);
}
constexpr auto s = "Hello"_xyz;
Test:
#include <array>
using atype = std::array<int, s.len>; // OK
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With