Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Length of user-defined string literal as a template argument?

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()>
like image 967
aschepler Avatar asked Jun 22 '13 15:06

aschepler


People also ask

What is string literal with example?

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."'

How do you define a string literal?

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.

What is difference between constants and literals?

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.

What is string literal operator?

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 .


1 Answers

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
like image 190
Kerrek SB Avatar answered Nov 13 '22 14:11

Kerrek SB