Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何对类模板中的私有嵌套类使用boost::intrusive_ptr_C++_Templates_C++11_Boost - Fatal编程技术网

C++ 如何对类模板中的私有嵌套类使用boost::intrusive_ptr

C++ 如何对类模板中的私有嵌套类使用boost::intrusive_ptr,c++,templates,c++11,boost,C++,Templates,C++11,Boost,假设我有一个列表类: 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_ad

假设我有一个
列表
类:

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
模板
班级名单{
...
私人:
类节点{
...
私人:
标准::尺寸\u t参考计数\u;
//由于访问私有成员refcount,节点的朋友_
friend void intrusive_ptr_add_ref(const node*p)noexcept;
friend void侵入性释放(const node*p)无异常;
};
//由于访问私有嵌套类节点,列表的朋友
friend void intrusive_ptr_add_ref(const node*p)noexcept;
friend void侵入性释放(const node*p)无异常;
boost::侵入性的{ptr节点{new node};
};
模板
void intrusive_ptr_add_ref(const typename list::node*p)无异常
{ ... }
模板
无效侵入性发布(const typename list::node*p)无例外
{ ... }
列表xs;//错误
上面的代码无法编译。错误是未定义
侵入式\u ptr\u add\u ref(list::node const*)
侵入式\u ptr\u release(list::node const*)
的符号


我想问题可能是我在
列表
节点
中将非模板函数声明为好友,但我定义的是函数模板。那么,正确的方法是什么呢?

这是内联好友定义大放异彩的情况之一:

#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;
}
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";
}
或类似

加分 如果您想使用详细的方法,我建议最明智的方法是在节点类型上参数化基础模板,而不是在列表元素上参数化基础模板(因为部分专门化不适用于函数模板)

以下是一些同样有效的方法:

#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;
}
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";
}
template void intrusive_ptr_add_ref(Node const*)无异常;
模板无效侵入性发布(节点常数*)无异常;
模板类列表{
类节点{
使用is_my_list_impl_nodetype=std::true_type;
std::大小\u t可变参考计数\u;
//由于访问私有嵌套类节点,列表的朋友
friend void intrusive_ptr_add_ref(node const*p)noexcept;
friend void侵入性释放(node const*p)无异常;
};
boost::侵入性的{ptr节点{new node};
};
模板
无效侵入性\u ptr\u添加\u ref(节点常数*p)无异常{
p->refcount_uz+=1;
}
模板
无效侵入性释放(节点常数*p)无例外{
如果(--p->refcount_u2;)
返回;

std::你最近不是问过这个吗?我有deja vúe的吗?在你声明它是朋友之前先声明它是入侵的_ptr_add_ref。模板函数像这样很有趣。@πάνταῥεῖ 他问了一个类似的问题:@πάνταῥεῖ 不,我没有。:-)@richardhoges-um…在声明其参数类型之前,我如何声明
侵入性的\u ptr\u add\u ref
?为了获得额外的分数,我画了一个更详细的例子,没有使用内联好友定义的优雅:当你在
列表::节点
的主体中定义好友函数时,它们会成为
列表
的f吗
list::node
的朋友,还是两者的朋友?@ZizhengTai仅限于node的()。但添加起来很容易: