2

我为这个例子的冗长道歉,我是从一个项目中设计出来的。注释的第 1 项和第 2 项在以下代码中很重要。

#include <boost/intrusive/set.hpp>

struct x : public boost::intrusive::set_base_hook<>
{
    int y;
};

struct finder
{
    bool operator()(const int & i, const x & _x) const
    { return i < _x.y;}
    bool operator()(const x & _x, const int & i) const
        { return _x.y < i;}
};

class trampoline
{
public:
    void bounce() const /* item 1 */
    {
        /*item 2*/
        boost::intrusive::set<x>::iterator it = _set.find(1,finder()); 
    }

    boost::intrusive::set<x> _set;
};

int main()
{
    trampoline t;
    t.bounce();
}

我不能将非常量迭代器带到我的成员容器(项目 2),其中范围内的函数是 const,如果我将迭代器切换到 const_iterator 一切正常,或者如果我使封闭函数非常量它也可以工作. 现在,经过一个小时的逆向工程,从以下错误消息中解决了问题,这很有意义:

test.cc:在成员函数 'void trampoline::bounce() const':test.cc:21: 错误:从 'boost::intrusive::tree_iterator<boost::intrusive::rbtree_impl<boost::intrusive 转换: :setopt<boost::intrusive::detail::base_hook_traits<x, boost::intrusive::rbtree_node_traits<void*, false>, (boost::intrusive::link_mode_type)1u, boost::intrusive::default_tag, 3 >, std::less<x>, long unsigned int, true> >, true>' 到非标量类型 'boost::intrusive::tree_iterator<boost::intrusive::rbtree_impl<boost::intrusive::setopt <boost::intrusive::detail::base_hook_traits<x, boost::intrusive::rbtree_node_traits<void*, false>, (boost::intrusive::link_mode_type)1u, boost::intrusive::default_tag, 3>, std::less<x>, long unsigned int, true> >, false>' 请求

最终导致我得到以下模板定义(/include/boost/intrusive/detail/tree_node.hpp +72):

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//                   Implementation of the tree iterator                   //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

// tree_iterator provides some basic functions for a 
// node oriented bidirectional iterator:
template<class Container, bool IsConst>

够了所以说我很快就解决了这个问题......

该模板是如何IsConst从封闭函数的调用点传递的?我的大脑已经准备好爆炸(据我所知,这很简单,但我很困惑)。详细的解释以及逐步实施来解释机制将是有帮助的。

关于 C++ 模板机制的类型推断/别名,我在这里有一个类似的问题。参考资料受到赞赏,但需要仔细考虑知识:D。如果你有耐心回答这个问题,你可能想尝试就另一个问题形成一个话语。

4

2 回答 2

1

像那样?

Foo<false> bar();
Foo<true> bar() const;
于 2011-03-16T17:26:16.177 回答
1

find() 成员函数不会boost::intrusive::set简单地具有 const 和非常量重载吗?我的意思是,我会这样做:

template <typename T /*...*/ >
class set {
  //... 
  public:
    template <bool isConst>
    class iterator {
      //....
    };
    iterator<true> find(/*..*/) const; //notice the const
    iterator<false> find(/*..*/);      //notice no const
};

这真的不是元编程魔法,只是很好的老式 const 正确性。

于 2011-03-16T17:27:34.630 回答