我在模板专业化方面遇到了一些麻烦。我已经找到了其他答案,并认为我在这个帖子中找到了解决方案 - Partial template specialization outside class definition - 然而事实证明这并没有解决我的问题。
我正在尝试基于枚举值进行一些模板特化,以消除对不必要的运行时多态性的需要。当我在类体中定义模板函数时,它工作正常,但是当我将定义移到类模板之外时,编译器无法匹配签名。
我的实际场景是与使用命名对象的API连接,我使用枚举值表示每个对象类。对象彼此不直接相关,但它们具有非常相似的资源管理/操作机制。我最初尝试使用特征,但因为我有时需要使用完全不同的函数签名,所以特征并没有像我希望的那样成功。
无论如何,这是我面临的问题的缩减示例。
狗吠工作,因为它是在类定义中定义的,但猫喵没有,因为它找不到喵喵的声明。如果我合并定义和声明猫喵将起作用。
有没有办法以这种方式部分指定模板?原因是我希望将外部API的依赖关系保存到源文件而不是头文件中。
enum class AnimalType { Dog, Cat, };
template<AnimalType Type> struct A;
template<>
struct A<AnimalType::Dog>
{
// OK
void bark() { std::cout << "woof"; }
};
template<>
struct A<AnimalType::Cat>
{
void meow();
};
// Cannot match
template <>
void A<AnimalType::Cat>::meow()
{
}
GCC 4.9抱怨
scratchpad/animal.h:105: error: template-id 'meow<>' for 'void <(AnimalType)1>::meow()' does not match any template declaration
void A<AnimalType::Cat>::meow()
由于
答案 0 :(得分:7)
此:
template<>
struct A<AnimalType::Cat> {
void meow();
};
使用非模板方法声明模板专门化。但是这个:
template <> void A<AnimalType::Cat>::meow()
意味着模板方法的专业化。由于A<AnimalType::Cat>
已经已完全专业化,因此此处不需要template <>
。
请改用:
void A<AnimalType::Cat>::meow() {
std::cout << "meow\n";
}
并考虑比较这种模板方法:
template<>
struct A<AnimalType::Cat> {
template <AnimalType> void greet();
};
template <>
void A<AnimalType::Cat>::greet<AnimalType::Cat>() {
std::cout << "purr\n";
}
template <>
void A<AnimalType::Cat>::greet<AnimalType::Dog>() {
std::cout << "flee\n";
}
答案 1 :(得分:2)
喜欢这样的作品:
// template <>
void A<AnimalType::Cat>::meow()
{
}
在定义具体类A&lt; AnimalType :: Cat&gt;的成员函数时。