gpt4 book ai didi

c++ - 如何专门化模板类中的模板方法?

转载 作者:太空狗 更新时间:2023-10-29 21:17:34 25 4
gpt4 key购买 nike

我发现 C++ 模板非常难以理解。现在我正在尝试专门化模板化类的模板化成员函数:

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++ 模板的核心工作原理吗?


简要介绍一下我在这里尝试做的事情:我还有一个二等舱 template <bool COW> class BaseSharedPointer这是一类共享指针,引用从 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++;}

请注意,您只能针对周围类模板的特化来特化成员函数。

但是,您的代码示例还有另外两个不完全正确的方面。首先,最好为 increaseRefCount 提供一个默认实现。 (这可以在类模板定义中完成)。二、你的两行

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

用于成员函数特化。原因是您没有定义类模板特化,而只是向前声明它们。但是,这不是必需的,因为您可以在不提供完整类模板特化的情况下特化成员函数。

这是一个完整的代码示例:

#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>();
}

Live Example .

更新:如果您不想要默认实现,您可以明确删除其他组合

template<> template<> void BaseReferencedObject<false>::increaseRefCount<true>() const = delete;
template<> template<> void BaseReferencedObject<true >::increaseRefCount<false >() const = delete;

当您只遗漏默认实现时,这会产生编译器错误而不是链接器错误。

关于c++ - 如何专门化模板类中的模板方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32623917/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com