考虑我有一个类模板,它以数组作为参数:
template <int N, const float numbers[N]>
class TemplateClass
{
public:
TemplateClass()
{
for (int i = 0; i < N; i++)
{
cout << numbers[i] << endl;
}
}
};
我可以像这样成功使用它:
const int N = 3;
extern const float Constants[N];
const float Constants[N] = { 2.0f, 2.1f, 2.2f };
int main()
{
TemplateClass<3, Constants>();
return 0;
}
但是,我尝试将构造函数方法体移到类声明之外是徒劳的:
// Fails with:
// error C2440: 'specialization' : cannot convert from 'const float *' to 'const float [3]'
template <int N, const float numbers[N]>
TemplateClass<N, numbers>::TemplateClass()
{
for (int i = 0; i < N; i++)
{
cout << numbers[i] << endl;
}
}
// Fails with:
// error C3860: template argument list following class template name must list parameters in the order used in template parameter list
// error C3855: 'TemplateClass<N,numbers>': template parameter 'numbers' is incompatible with the declaration
template <int N, const float* numbers>
TemplateClass<N, numbers>::TemplateClass()
{
for (int i = 0; i < N; i++)
{
cout << numbers[i] << endl;
}
}
这在VC ++ 11和VC ++ 12编译器上都可以看到。我该如何解决这个问题?
答案 0 :(得分:2)
根据标准§14.1/ 4,非类型模板参数必须具有以下类型之一:
lvalue
引用对象或lvalue
对函数的引用,std::nullptr_t
。 const float numbers[N]
不属于上述情况。另见(https://stackoverflow.com/a/16214727/2352671)
现在仍然存在的问题是为什么当您在线定义构造函数(即,在类的定义中)时,您的程序编译并运行正常。
这个问题的答案是 Non-type template parameters that are declared as arrays or functions are converted to pointers or pointers to functions, respectively. 我们可以通过打印类型来确认
在内联构造函数中的numbers
:
template <int N, const float numbers[N]>
class TemplateClass
{
public:
TemplateClass()
{
std::cout << typeid(numbers).name() << std::endl;
for (int i = 0; i < N; i++)
{
std::cout << numbers[i] << std::endl;
}
}
};
我们得到的输出是:
float const *
因此,标准不会受到侵犯,代码也会起作用。
我们要回答的下一个问题是,当您使用参数模板列表template <int N, const float *numbers>
定义类定义之外的构造函数时
你得到一个编译错误。
这个问题的答案是因为您的类定义中的参数列表(即template <int N, const float numbers[N]>
)和构造定义中的参数列表不匹配。
#include <iostream>
using namespace std;
template <int N, const float* numbers>
class TemplateClass
{
public:
TemplateClass();
};
template <int N, const float *numbers>
TemplateClass<N, numbers>::TemplateClass()
{
for (int i = 0; i < N; i++)
{
cout << numbers[i] << endl;
}
}
const int N = 3;
extern const float Constants[N];
const float Constants[3] = { 2.0f, 2.1f, 2.2f };
int main()
{
TemplateClass<3, Constants>();
return 0;
}
2
2.1
2.2
答案 1 :(得分:-1)
模板方法必须在模板类的同一文件头中定义。模板只是一个声明,当您将它用于变量时,它会被编译器实例化,因此模板方法无法在cpp文件中实现。