如何在模板 class 中特化模板方法?
How to specialize templated method in templated class?
我发现 C++ 模板非常难以理解。现在我正在尝试专门化模板化 class:
的模板化成员函数
template <bool COW>
class BaseReferencedObject {
public:
BaseReferencedObject() : refCount(0) {}
BaseReferencedObject(const BaseReferencedObject<COW>&) : refCount(0) {}
BaseReferencedObject<COW>& operator=(const BaseReferencedObject<COW>&) {return *this;}
template <bool COW2> void increaseRefCount() const;
void decreaseRefCount() const {refCount--;}
int getRefCount() const {return refCount;}
private:
mutable int refCount;
};
class BaseReferencedObject<false>;
class BaseReferencedObject<true >;
template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
template<> void BaseReferencedObject<true >::increaseRefCount<true >() const {refCount++;}
typedef BaseReferencedObject<false> ReferencedObject;
typedef BaseReferencedObject<true > SharedData ;
但是,当我尝试编译这段代码时,我得到
SharedPtr.hh:31:62: error: expected initializer before ‘<’ token
template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
^
这是什么意思,我应该如何继续执行此操作?我试图通过谷歌搜索找到解决方案,但我找不到任何可以解决的问题有效。
顺便问一下,有人可以推荐任何好的资源来更好地理解 C++ 模板的核心工作原理吗?
关于我在这里尝试做的事情的简要说明:我还有第二个 class template <bool COW> class BaseSharedPointer
,它是一个 class 引用对象的共享指针,这些对象继承自 ReferencedObject
或来自 SharedData
。这个想法是只有使用 copy-on-write (COW) 的共享指针应该能够引用应该在写入时复制的对象(真-真组合),并且只有不使用的共享指针COW 应该能够引用不应在写入时复制的对象(假 - 假组合)。不应允许其他两种组合(真-假、假-真),因为混合使用 COW 的智能指针和不使用 COW 的智能指针被认为是一个坏主意。因此,我试图通过只为允许的组合实例化 increaseRefCount
方法的特化来使这些组合变得不可能,并且如果某些代码试图使用其中任何一个。
您需要添加另一个 template<>
来专门化成员函数
template<> template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
template<> template<> void BaseReferencedObject<true >::increaseRefCount<true >() const {refCount++;}
请注意,您只能针对周围 class 模板的特化来特化成员函数。
但是,您的代码示例还有另外两个方面不完全正确。首先,最好为 increaseRefCount
提供默认实现(这可以在 class 模板定义中完成)。二、你的两行
class BaseReferencedObject<false>;
class BaseReferencedObject<true >;
导致您在评论中提到的有点神秘的编译器错误。如果你 use clang instead of g++ 作为编译器,你会得到这些行的更清晰的错误:
error: template specialization requires 'template<>'
以及错误
error: incomplete type 'BaseReferencedObject' named in nested name specifier
用于成员函数专业化。原因是您没有定义 class 模板特化,而只是向前声明它们。但是,这不是必需的,因为您可以在不提供完整的 class 模板特化的情况下特化成员函数。
这是一个完整的代码示例:
#include <iostream>
template <bool COW>
class BaseReferencedObject {
public:
BaseReferencedObject() : refCount(0) {}
BaseReferencedObject(const BaseReferencedObject<COW>&) : refCount(0) {}
BaseReferencedObject<COW>& operator=(const BaseReferencedObject<COW>&) {return *this;}
template <bool COW2> void increaseRefCount() const { std::cout << "DEFAULT\n"; refCount++; }
void decreaseRefCount() const {refCount--;}
int getRefCount() const {return refCount;}
private:
mutable int refCount;
};
template<> template<> void BaseReferencedObject<false>::increaseRefCount<false>() const { std::cout << "FALSE\n"; refCount++;}
template<> template<> void BaseReferencedObject<true >::increaseRefCount<true >() const { std::cout << "TRUE \n"; refCount++;}
typedef BaseReferencedObject<false> ReferencedObject;
typedef BaseReferencedObject<true > SharedData ;
int main()
{
BaseReferencedObject<false> b0;
BaseReferencedObject<true > b1;
b0.increaseRefCount<false>();
b0.increaseRefCount<true>();
b1.increaseRefCount<true >();
b1.increaseRefCount<false>();
}
更新:如果不想要默认实现,可以显式删除其他组合
template<> template<> void BaseReferencedObject<false>::increaseRefCount<true>() const = delete;
template<> template<> void BaseReferencedObject<true >::increaseRefCount<false >() const = delete;
当您只遗漏默认实现时,这会产生编译器错误而不是链接器错误。
我发现 C++ 模板非常难以理解。现在我正在尝试专门化模板化 class:
的模板化成员函数template <bool COW>
class BaseReferencedObject {
public:
BaseReferencedObject() : refCount(0) {}
BaseReferencedObject(const BaseReferencedObject<COW>&) : refCount(0) {}
BaseReferencedObject<COW>& operator=(const BaseReferencedObject<COW>&) {return *this;}
template <bool COW2> void increaseRefCount() const;
void decreaseRefCount() const {refCount--;}
int getRefCount() const {return refCount;}
private:
mutable int refCount;
};
class BaseReferencedObject<false>;
class BaseReferencedObject<true >;
template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
template<> void BaseReferencedObject<true >::increaseRefCount<true >() const {refCount++;}
typedef BaseReferencedObject<false> ReferencedObject;
typedef BaseReferencedObject<true > SharedData ;
但是,当我尝试编译这段代码时,我得到
SharedPtr.hh:31:62: error: expected initializer before ‘<’ token
template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
^
这是什么意思,我应该如何继续执行此操作?我试图通过谷歌搜索找到解决方案,但我找不到任何可以解决的问题有效。
顺便问一下,有人可以推荐任何好的资源来更好地理解 C++ 模板的核心工作原理吗?
关于我在这里尝试做的事情的简要说明:我还有第二个 class template <bool COW> class BaseSharedPointer
,它是一个 class 引用对象的共享指针,这些对象继承自 ReferencedObject
或来自 SharedData
。这个想法是只有使用 copy-on-write (COW) 的共享指针应该能够引用应该在写入时复制的对象(真-真组合),并且只有不使用的共享指针COW 应该能够引用不应在写入时复制的对象(假 - 假组合)。不应允许其他两种组合(真-假、假-真),因为混合使用 COW 的智能指针和不使用 COW 的智能指针被认为是一个坏主意。因此,我试图通过只为允许的组合实例化 increaseRefCount
方法的特化来使这些组合变得不可能,并且如果某些代码试图使用其中任何一个。
您需要添加另一个 template<>
来专门化成员函数
template<> template<> void BaseReferencedObject<false>::increaseRefCount<false>() const {refCount++;}
template<> template<> void BaseReferencedObject<true >::increaseRefCount<true >() const {refCount++;}
请注意,您只能针对周围 class 模板的特化来特化成员函数。
但是,您的代码示例还有另外两个方面不完全正确。首先,最好为 increaseRefCount
提供默认实现(这可以在 class 模板定义中完成)。二、你的两行
class BaseReferencedObject<false>;
class BaseReferencedObject<true >;
导致您在评论中提到的有点神秘的编译器错误。如果你 use clang instead of g++ 作为编译器,你会得到这些行的更清晰的错误:
error: template specialization requires 'template<>'
以及错误
error: incomplete type 'BaseReferencedObject' named in nested name specifier
用于成员函数专业化。原因是您没有定义 class 模板特化,而只是向前声明它们。但是,这不是必需的,因为您可以在不提供完整的 class 模板特化的情况下特化成员函数。
这是一个完整的代码示例:
#include <iostream>
template <bool COW>
class BaseReferencedObject {
public:
BaseReferencedObject() : refCount(0) {}
BaseReferencedObject(const BaseReferencedObject<COW>&) : refCount(0) {}
BaseReferencedObject<COW>& operator=(const BaseReferencedObject<COW>&) {return *this;}
template <bool COW2> void increaseRefCount() const { std::cout << "DEFAULT\n"; refCount++; }
void decreaseRefCount() const {refCount--;}
int getRefCount() const {return refCount;}
private:
mutable int refCount;
};
template<> template<> void BaseReferencedObject<false>::increaseRefCount<false>() const { std::cout << "FALSE\n"; refCount++;}
template<> template<> void BaseReferencedObject<true >::increaseRefCount<true >() const { std::cout << "TRUE \n"; refCount++;}
typedef BaseReferencedObject<false> ReferencedObject;
typedef BaseReferencedObject<true > SharedData ;
int main()
{
BaseReferencedObject<false> b0;
BaseReferencedObject<true > b1;
b0.increaseRefCount<false>();
b0.increaseRefCount<true>();
b1.increaseRefCount<true >();
b1.increaseRefCount<false>();
}
更新:如果不想要默认实现,可以显式删除其他组合
template<> template<> void BaseReferencedObject<false>::increaseRefCount<true>() const = delete;
template<> template<> void BaseReferencedObject<true >::increaseRefCount<false >() const = delete;
当您只遗漏默认实现时,这会产生编译器错误而不是链接器错误。