Type-dependent 模板函数中的常量

Type-dependent constant in template function

我想要一个模板化函数中的静态数组,其长度取决于函数专门化的类型。我的第一次尝试是:

Header:

template<typename T>
struct Length {
    const static size_t len;
};

template<typename T>
void func(){
  static T vars[Length<T>::len]; // len not const. according to compiler!
  // ...
}

源文件:

template<> const size_t Length<double>::len = 2;
template<> const size_t Length<float>::len = 1;
// ...

但是,g++ 没有编译它并抱怨

error: storage size of ‘vars’ isn’t constant

那么,这里到底有什么问题呢?我知道 fixed-length 数组的大小需要是一个常量并且在编译时已知,但这里似乎就是这种情况。 当我写

const size_t len = 2;

void func(){
    static double vars[len];
}

编译没有问题。

问题:

代码有什么问题,有哪些替代方案可以实现所需的行为?我不想在运行时分配内存...

要将 const 变量视为 compile-time 常量(形式上,常量表达式),其值必须在使用时可用.这意味着专门的定义必须转到 header 文件。

如果像您那样仅对成员进行专业化处理,我相信会给您一个 multiple-definition 错误。专门化整个 class 模板并保持静态成员定义内联应该没问题:

template<typename T>
struct Length;

template <>
struct Length<double>
{
  static const size_t len = 2;
};

附带说明一下,您的程序最初是无效的:必须在使用前声明显式特化。这意味着您必须至少 声明 len 在 header 中(或您打算使用它的任何地方)的专业化。

下面的代码用 g++ 4.6.3 编译对我来说很好,并产生输出

2
1

array.cpp:

#include <cstddef>
#include <iostream>

template<typename T>
struct Length {
    const static size_t len;
};

template<typename T>
void func(){
  static T vars[Length<T>::len]; 
  std::cout << (sizeof(vars) / sizeof(*vars)) << std::endl;
}

template<> const size_t Length<double>::len = 2;
template<> const size_t Length<float>::len = 1;

int main(){
  func<double>();
  func<float>();
}
$ make array
g++     array.cpp   -o array
$ ./array 
2
1