如何将boost::intrusive_ptr用于类模板中的私有嵌套类
How to use boost::intrusive_ptr for private nested class within class template
假设我有一个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*)
和intrusive_ptr_release(list<int>::node const*)
的未定义符号。
我认为问题可能是我在list
和node
中将非模板函数声明为友元,但我定义的是函数模板。那么,正确的方法是什么呢?
这是内联好友定义大放异彩的场合之一:
在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类型上参数化基本模板,而不是列表元素(因为部分专业化不适用于函数模板)。
以下内容也有效:
在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";
}
如果在使用其他addref/release方法的翻译单元中使用了更具侵入性的指针,那么is_my_list_impl_nodetype
上的整个SFINAE是为了防止打开模板创建不明确的重载。
相关文章:
- 嵌套列表,用于在 C++ 中实现邻接列表
- 无法获得等效的 std::less 来用于嵌套迭代器
- 用于返回嵌套类类型的作用域解析运算符
- 用于在一维数组上嵌套循环操作的正确 openmp 指令
- 模板函数,用于从多个嵌套unordered_map中提取值
- 用于更简洁代码的嵌套命名空间
- 简单的C 嵌套以用于循环程序,以打印带有星星错误的正方形
- C /STL公共迭代器,用于深嵌套的私人数据
- C 误差C2064用于C 模板中的嵌套结合
- CFG 和 PDA 用于具有完美嵌套括号和括号的语法
- 嵌套 2 用于推入向量的循环,尽量不重复push_back值
- 嵌套c++11范围循环,用于查找组合
- 将OpenMP应用于C++中的特定嵌套循环
- C++中用于嵌套循环的OpenMP编程的锁定策略
- 嵌套,用于在java中不按预期工作
- 嵌套循环,用于显示 25 个字符的行 c++
- openMP 嵌套并行用于循环与内部并行
- 重载运算符<<用于嵌套类模板
- 用于顺序内存访问的编译器嵌套循环优化
- 使嵌套类型哈希能够用于std::unordered_set