捕获数组模板参数的大小
Capture size of array template parameter
在使用数组非模板类型参数时,好像size信息不单独传递的话基本是无法恢复的。例如,在模板中
template<const char CStr[]>
struct ToTemp {
...
}
任何对 sizeof(CStr)
的引用都将 return 8(或 4,取决于您的系统),因为它实际上是 const char *
。你可以声明
template<const char CStr[5]>
struct ToTemp {
...
}
或
template<int N, const char CStr[N]>
struct ToTemp {
...
}
但是第一个需要在编写 class 时知道实际大小(不是很有用),第二个需要单独传递大小(在这里没有用 - 可能是对于强制执行大小限制很有用)。理想情况下我会有类似
的东西
template<const char CStr[int N]> //Let the compiler infer N based on the type
struct ToTemp {
...
}
或
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 {
...
}
...但当然这些都不起作用。最后,我希望能够写
const char foo[] = "abcd";
ToTemp<foo> bar;
并让 bar
正确理解 sizeof(foo)
是 5,而无需传入单独的 sizeof(foo)
模板参数。
您可以使用全局字符串文字作为模板参数来匹配 const char[]
并通过 constexpr 函数计算长度:
constexpr size_t GetSize(const char str[])
{
for (size_t i = 0; ; ++i)
{
if (str[i] == '[=10=]')
{
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, "");
}
在使用数组非模板类型参数时,好像size信息不单独传递的话基本是无法恢复的。例如,在模板中
template<const char CStr[]>
struct ToTemp {
...
}
任何对 sizeof(CStr)
的引用都将 return 8(或 4,取决于您的系统),因为它实际上是 const char *
。你可以声明
template<const char CStr[5]>
struct ToTemp {
...
}
或
template<int N, const char CStr[N]>
struct ToTemp {
...
}
但是第一个需要在编写 class 时知道实际大小(不是很有用),第二个需要单独传递大小(在这里没有用 - 可能是对于强制执行大小限制很有用)。理想情况下我会有类似
的东西template<const char CStr[int N]> //Let the compiler infer N based on the type
struct ToTemp {
...
}
或
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 {
...
}
...但当然这些都不起作用。最后,我希望能够写
const char foo[] = "abcd";
ToTemp<foo> bar;
并让 bar
正确理解 sizeof(foo)
是 5,而无需传入单独的 sizeof(foo)
模板参数。
您可以使用全局字符串文字作为模板参数来匹配 const char[]
并通过 constexpr 函数计算长度:
constexpr size_t GetSize(const char str[])
{
for (size_t i = 0; ; ++i)
{
if (str[i] == '[=10=]')
{
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, "");
}