gpt4 book ai didi

c++ - 如何将 boost::intrusive_ptr 用于类模板中的私有(private)嵌套类

转载 作者:行者123 更新时间:2023-11-30 05:24:53 26 4
gpt4 key购买 nike

假设我有一个 list类:

template<typename T>
class list {
...

private:
class node {
...

private:
std::size_t refcount_;

// friends of node because accessing private member refcount_
friend void intrusive_ptr_add_ref(const node* p) noexcept;
friend void intrusive_ptr_release(const node* p) noexcept;
};

// friends of list because accessing private nested class node
friend void intrusive_ptr_add_ref(const node* p) noexcept;
friend void intrusive_ptr_release(const node* p) noexcept;

boost::intrusive_ptr<node> node_{new node};
};

template<typename T>
void intrusive_ptr_add_ref(const typename list<T>::node* p) noexcept
{ ... }

template<typename T>
void intrusive_ptr_release(const typename list<T>::node* p) noexcept
{ ... }

list<int> xs; // error

上面的代码无法编译。错误是 intrusive_ptr_add_ref(list<int>::node const*) 的 undefined symbol 和 intrusive_ptr_release(list<int>::node const*) .

我认为问题可能是我在 list 中将非模板函数声明为友元和 node ,但我定义的是函数模板。那么正确的做法是什么?

最佳答案

这是内联 friend 定义大放异彩的场合之一:

Live On Coliru

#include <iostream>
#include <boost/intrusive_ptr.hpp>

template<typename T> class list {
class node {
std::size_t mutable refcount_;

// friends of list because accessing private nested class node
friend void intrusive_ptr_add_ref(node const* p) noexcept {
p->refcount_ += 1;
}
friend void intrusive_ptr_release(node const* p) noexcept {
if (--p->refcount_)
return;
std::cout << "freeing node " << static_cast<void const*>(p) << "\n";
}
};

boost::intrusive_ptr<node> node_{new node};
};

int main() {
list<int> xs;
}

打印

freeing node 0x19b7c20

或类似的

奖励积分

如果你想走冗长的路线,我建议最明智的方法是在 Node 类型上参数化基本模板,而不是列表元素(因为部分特化不与函数模板一起使用)。

下面的方法也行得通:

Live On Coliru

template <typename Node, typename = typename Node::is_my_list_impl_nodetype> void intrusive_ptr_add_ref(Node const*) noexcept;
template <typename Node, typename = typename Node::is_my_list_impl_nodetype> void intrusive_ptr_release(Node const*) noexcept;

template<typename T> class list {
class node {
using is_my_list_impl_nodetype = std::true_type;

std::size_t mutable refcount_;

// friends of list because accessing private nested class node
friend void intrusive_ptr_add_ref<node, std::true_type>(node const* p) noexcept;
friend void intrusive_ptr_release<node, std::true_type>(node const* p) noexcept;
};

boost::intrusive_ptr<node> node_{new node};
};

template<typename Node, typename>
void intrusive_ptr_add_ref(Node const* p) noexcept {
p->refcount_ += 1;
}

template<typename Node, typename>
void intrusive_ptr_release(Node const* p) noexcept {
if (--p->refcount_)
return;
std::cout << "freeing node " << static_cast<void const*>(p) << "\n";
}

整体SFINAE on is_my_list_impl_nodetype如果您在使用其他 addref/release 方法的翻译单元中有更多侵入性指针使用,是为了防止开放模板创建模棱两可的重载。

关于c++ - 如何将 boost::intrusive_ptr 用于类模板中的私有(private)嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38536677/

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