C ++ Template meta-magic,模板调用站点资格扣除机制

时间:2011-03-16 17:13:19

标签: c++ templates boost generic-programming const-correctness

我为这个例子的冗长而道歉,我把它从一个项目中剔除了。注释,第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();
}

我不能将非const的迭代器带到我的成员容器(第2项),其中作用域中的函数是const,如果我将迭代器切换到const_iterator一切正常,或者如果我使封闭函数非const它也有效。现在,经过一个小时的逆向工程后,出现以下错误信息的问题:

  

test.cc:在成员函数'void trampoline :: bounce()const':test.cc:21:error:从'boost :: intrusive :: tree_iterator&lt; boost :: intrusive :: rbtree_impl&lt; boost:转换: :intrusive :: setopt&lt; boost :: intrusive :: detail :: base_hook_traits&lt; x,boost :: intrusive :: rbtree_node_traits&lt; void *,false&gt;,(boost :: intrusive :: link_mode_type)1u,boost :: intrusive :: default_tag,3&gt ;,std :: less&lt; x&gt ;,长unsigned int,true&gt; &gt;,true&gt;'到非标量类型'boost :: intrusive :: tree_iterator&lt; boost :: intrusive :: rbtree_impl&lt; boost :: intrusive :: setopt&lt; boost :: intrusive :: detail :: base_hook_traits&lt; x,boost :: intrusive :: rbtree_node_traits&lt; void *,false&gt;,(boost :: intrusive :: link_mode_type)1u,boost :: intrusive :: default_tag,3&gt ;,std :: less&lt; x&gt ;,long unsigned int,true&gt; &gt;,false&gt;'required

最终导致我进入以下模板定义(/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?我的大脑已准备好爆炸(因为我知道它的一些简单,但我很神秘)。通过逐步实施来解释机制的详细解释将是有帮助的。

我有一个类似的问题here类似于C ++模板机制的类型推导/别名。参考文献被赞赏,但他们需要仔细考虑知识:D。如果你有耐心回答这个问题,你可能想尝试在另一个问题上形成话语。

2 个答案:

答案 0 :(得分:1)

是那样的?

Foo<false> bar();
Foo<true> bar() const;

答案 1 :(得分:1)

boost::intrusive::set的find()成员函数不会只有const和非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
};

这真的不是元编程的魔力,只是很好的旧时尚的正确性。