模板函数中的类型相关常量

时间:2015-04-11 09:09:50

标签: c++ arrays templates template-specialization

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

部首:

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++无法编译并抱怨

  

错误:'vars'的存储大小不是常数

那么,究竟是什么问题呢?我知道固定长度数组的大小需要是一个常量并且在编译时已知,但这似乎就是这种情况。 我写的时候

const size_t len = 2;

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

它编译没有问题。

问题:

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

2 个答案:

答案 0 :(得分:5)

要将const变量视为编译时常量(正式地,常量表达式),其值必须在使用时可用。这意味着专门的定义必须转到头文件。

如果只是作为成员的专业化完成,就像你所做的那样,我认为会给你一个多重定义错误。您可以使用专门化整个类模板,并保持静态成员定义内联:

template<typename T>
struct Length;

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

作为附注,您的程序最初是无效的:必须在使用前声明显式特化。这意味着您必须至少声明标题中的len的特化(或您打算使用它的任何地方)。

答案 1 :(得分:1)

以下代码使用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