User-defined class template argument deduction guide to deduce size of constexpr string_view

Viewed 184

How to write the user-defined class template argument deduction guide to deduce the size of a constexpr std::string_view?

I want to implement a fixed-length, mutable String. With the help from the C++17 class template argument deduction (CTAD) technique, the user of this String can skip specifying the size N as the template argument when he initializes the String from a string literal.

Now I want to enable the same omission if the user initializes the String from a constexpr std::string_view. But I do not know how to write the class template argument deduction guide for this case.

The following minimal code that compiles with g++ -std=c++17 illustrates my case

#include <cstddef>
#include <cstring>
#include <iostream>
#include <string>
#include <string_view>

template<std::size_t N>
struct String
{
    char carr[N] {};

    String(const char * cstr)
    {
        std::memcpy(carr, cstr, N);
    }

    String(const std::string_view & sv)
    {
        std::memcpy(carr, sv.data(), N);
    }

    constexpr std::size_t size() const
    {
        return N;
    }
};

// user-defined class template argument deduction guide for string literal
template<std::size_t N> String(const char (&)[N]) -> String<N-1>;

int main()
{
    String s1("hello");
    static_assert(s1.size() == 5);

    constexpr std::string_view sv("view");
    String<4> s2(sv);
    static_assert(s2.size() == 4);

    // Question: How to write class template argument deduction guide
    //           so that the following lines would compile?
    // String s3(sv);
    // static_assert(s3.size() == 4);

    return 0;
}

Question: How to write the class template argument deduction guide to deduce size of constexpr string_view so that the commmented code lines in the code would compile?

0 Answers
Related