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.