【问题标题】:c++ function code generalization using templatec++函数代码泛化使用模板
【发布时间】:2012-05-05 16:30:58
【问题描述】:

我正在编写一个类似 stl 的容器类,它具有以下功能:

    Iterator begin(){
        return Iterator(data_.begin(), 1);
    }

    ConstIterator begin() const{
        return ConstIterator(data_.begin(), 1);
    }

我想我可以用一个函数来替换两者:

    template <typename itr0, typename itr1>
    itr0 begin(){
        return itr1(data_.begin(), 1);
    }

当我调用以下代码时,代码是在编译时生成的:

    Iterator it = foo.begin<Iterator, Iterator>();
    ConstIterator it = foo.begin<ConstIterator const?, ConstIterator>();

我的第一个问题是,ConstIterator begin() const 实际上是什么类型名?

其次,有没有办法让这个元编程在课堂之外是透明的?即我仍然可以使用以下代码调用 begin() 就好像它是以标准方式编写的一样?

    C foo;
    const C foo2;
    Iterator it = foo.begin();
    ConstIterator it = foo2.begin();

【问题讨论】:

  • 为什么要在 begin 方法中使用 2 个模板参数?
  • @fontanini hmm 因为我不确定 ConstIterator begin() const 有什么类型名,所以对于 const 情况,itr0 和 itr1 是否相同。

标签: c++ templates iterator metaprogramming containers


【解决方案1】:

不幸的是,您需要分别定义这两种方法,因为正如您所指出的,它们的签名因const 修饰符而异。没有可用的模板魔法可以克服这个问题(至少我知道没有)。

但是,您可以使用多种不同的技术将它们的实现组合成一个方法。这是一个这样的选项,可以避免任何const_cast'ing:

struct Container
{
    template< typename I, typename C >
    friend I begin_impl( C & c ){
      return I( c.data_.begin(), 1 );
    }

    Iterator begin(){
        return begin_impl< Iterator >( *this ); // *this is "Container"
    }

    ConstIterator begin() const{
        return begin_impl< ConstIterator >( *this ); // *this is "Container const"
    }
};

更多选项请参见here

【讨论】:

  • typename C 对我来说看起来很奇怪,为什么不直接使用Container
  • @user2k5 对不起,我可以说得更清楚。当从begin() 调用时,C 将是Container。但是当从begin() const 调用时,C 将是Container const
  • @AndrewDurward 感谢您的回答。如果存在解决方案,这是其中之一,很容易找到它。但如果不存在,我需要找人确认:)
  • @Andrew 在这种情况下很好地使用了模板和很好的解释。而且你真的不需要说对不起...... :)
  • @AndrewDurward 我的 c++ 技能有点失败...如果我将您的代码直接放入我的项目中,则后两个函数看不到 begin_impl ...错误是“未声明的 begin_impl "
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多