我需要定义一个具有非类型模板参数的类并专门化其函数成员之一。下面的代码是我需要做的事情的合理简化(我们可以假设这是 c++11,但我不认为 C++ 标准是这里的问题)。
template <class T, std::size_t LIMIT=100>
struct A {
std::array<T,LIMIT> array;
void print (T value) {
std::cout << LIMIT << std::endl;
std::cout << value << std::endl;
}
};
template<>
void A<float>::print(float value) {
std::cout << LIMIT << std::endl;
std::cout << value*10.0 << std::endl;
}
int main (int argc, const char** argv) {
A<float> a;
a.print(23.3);
}
当我编译它时(g++ 9.4.),我收到此错误:
test.cpp: In member function ‘void A<T, LIMIT>::print(T) [with T = float; long unsigned int LIMIT = 100]’:
test.cpp:20:16: error: ‘LIMIT’ was not declared in this scope
20 | std::cout << LIMIT << std::endl;
| ^~~~~
这非常令人惊讶,因为在我看来,编译器非常清楚 LIMIT 是什么(“long unsigned int LIMIT = 100”)。
如果我这样实现该功能:
template<>
void A<float, std::size_t LIMIT=100>::print(float value) {
std::cout << LIMIT << std::endl;
std::cout << value*10.0 << std::endl;
}
我反而得到了另一个错误:
test.cpp:18:36: error: template argument 2 is invalid
18 | void A<float, std::size_t LIMIT=100>::print(float value) {
| ^
test.cpp:18:56: error: ‘print’ is not a template function
18 | void A<float, std::size_t LIMIT=100>::print(float value) {
|
我怀疑函数成员专业化和非类型参数存在一些我不知道的限制。
PS:这是一些将在嵌入式系统中运行的代码的示例,所以我实际上需要非类型参数,这是不可协商的。
我尝试过但没有成功
template<>
void A<float>::print(float value) {
std::cout << LIMIT << std::endl;
std::cout << value*10.0 << std::endl;
}
template<>
void A<float, std::size_t LIMIT>::print(float value) {
std::cout << LIMIT << std::endl;
std::cout << value*10.0 << std::endl;
}
和
template<>
void A<float, std::size_t LIMIT=100>::print(float value) {
std::cout << LIMIT << std::endl;
std::cout << value*10.0 << std::endl;
}
您不能仅专门化一种成员方法,这意味着您必须部分专门化该类:
#include <array>
#include <iostream>
template <class T, std::size_t LIMIT=100>
struct A
{
std::array<T,LIMIT> array;
void print (T value)
{
std::cout << LIMIT << std::endl;
std::cout << value << std::endl;
}
};
template <std::size_t LIMIT>
struct A<float,LIMIT>
{
void print (float value)
{
std::cout << LIMIT << std::endl;
std::cout << 10.0*value << std::endl;
}
};
int main (int argc, const char** argv)
{
A<float>{}.print(23.35);
A<int>{}.print(23);
}