简体   繁体   中英

Capture size of array template parameter

When using an array non-template type parameter, it seems that size information is basically impossible to recover without passing it separately. For example, in a template

template<const char CStr[]>
struct ToTemp {
 ...
}

any references to sizeof(CStr) will return 8 (or 4, depending on your system), because it's actually a const char * . You can declare

template<const char CStr[5]>
struct ToTemp {
 ...
}

or

template<int N, const char CStr[N]>
struct ToTemp {
 ...
}

but the first one requires knowing the actual size when you're writing the class (not very useful), and the second one requires passing in the size separately anyway (not useful here -- could be useful for enforcing size constraints). Ideally I would have something like

template<const char CStr[int N]> //Let the compiler infer N based on the type
struct ToTemp {
 ...
}

or

template<int N = -1, const char CStr[N]> //Declare N but let it be forced to a given value, so that I don't have to pass it in 
struct ToTemp {
 ...
}

... but of course neither of those work. In the end, I want to be able to write

const char foo[] = "abcd";
ToTemp<foo> bar;

and have bar correctly understand that sizeof(foo) is 5, without having to pass in a separate sizeof(foo) template argument.

You can use global string literals as a template parameter to match const char[] and calculate length via constexpr function:

constexpr size_t GetSize(const char str[])
{
    for (size_t i = 0; ; ++i)
    {
        if (str[i] == '\0')
        {
            return i;
        }
    }
}

template <const char str[]>
struct X
{
    constexpr static auto Size = GetSize(str);
};

constexpr const char string[] = "42";

void foo()
{
    X<string> x;
    static_assert(X<string>::Size == 2, "");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM