简体   繁体   English

捕获数组模板参数的大小

[英]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 * .任何对sizeof(CStr)引用都将返回 8(或 4,取决于您的系统),因为它实际上是一个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.并且让bar正确理解sizeof(foo)是 5,而不必传入单独的sizeof(foo)模板参数。

You can use global string literals as a template parameter to match const char[] and calculate length via constexpr function:您可以使用全局字符串文字作为模板参数来匹配const char[]并通过 constexpr 函数计算长度:

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, "");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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