我想将模板化函数的专业化实现放到一个单独的源文件中,但是如果我尝试调用它(在MyAction中),则会出现此错误:
Explicit specialization has already been instantiated
我不知道为什么会出现此错误。 示例代码:
main.cpp
#include <iostream>
#include <string>
#include "MyClass.h"
int main()
{
std::cout << "Hello, " << XX::MyClass().MyMethod<1>() << std::endl;
std::cin.get();
}
MyClass.h
#pragma once
#include <string>
namespace XX {
struct MyClass {
std::string MyAction() {
return MyMethod<0>() + MyMethod<1>();
}
template<int>
std::string MyMethod();
};
template<>
std::string MyClass::MyMethod<0>();
template<>
std::string MyClass::MyMethod<1>();
}
MyClass.cpp
#include "MyClass.h"
namespace XX {
template<>
std::string MyClass::MyMethod<0>() {
return "FOO";
}
template<>
std::string MyClass::MyMethod<1>() {
return "BAR";
}
}
是否存在我不知道的模板实例化规则?
答案 0 :(得分:4)
好的,问题似乎是订单。
在定义MyAction
时,编译器尝试实例化模板,但他不了解专门化知识。
当您声明MyAction
并在模板专门化后在cpp中定义它时,它将起作用。
// header part
#include <string>
namespace XX {
struct MyClass {
template<int>
std::string MyMethod();
std::string MyAction();
};
}
// cpp part
namespace XX {
template<>
std::string MyClass::MyMethod<0>() {
return "a";
}
template<>
std::string MyClass::MyMethod<1>() {
return "b";
}
std::string MyClass::MyAction() {
return MyMethod<0>() + MyMethod<1>();
}
}
参见此处:https://godbolt.org/z/aGSB21
请注意,如果您将MyClass::MyAction()
移到MyClass::MyMethod<1>()
上方,错误会再次出现。
此处是可以在头文件中声明特殊化的版本:https://godbolt.org/z/kHjlne