类定义之外的部分模板特化定义

时间:2015-08-07 12:49:52

标签: c++ templates c++11

我在模板专业化方面遇到了一些麻烦。我已经找到了其他答案,并认为我在这个帖子中找到了解决方案 - 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()

由于

2 个答案:

答案 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;的成员函数时。