c++c++11static-assertcompile-time-constantuser-defined-literals

User-defined literal string: compile-time length check


I have a user-defined literal operator that only makes sense for strings of a specific length, like this:

constexpr uint16_t operator "" _int(const char* s, std::size_t len)
{
    return len == 2 ? s[0] | (s[1] << 8) : throw;
}

This works:

"AB"_int // equals 16961

But this also compiles, and I don't want it to:

"ABC"_int // throws at runtime

I tried static_assert(len == 2), but it isn't allowed in a constexpr function.

How can I make "ABC"_int cause an error at compile time?


Solution

  • With C++20 you can use consteval and a normal assert (or whatever exception you like):

    #include <iostream>
    #include <cstdint>
    #include <cassert>
    
    consteval uint16_t operator "" _int(const char* s, size_t len)
    {
        assert(len == 2);
        return s[0] | (s[1] << 8);
    }
    
    int main() {
        std::cout << "AB"_int << std::endl;
        //std::cout << "ABC"_int << std::endl;  // compiler error
    
        return 0;
    }