临时问题和运算符重载问题

时间:2014-02-02 15:59:30

标签: c++ operator-overloading

我正在处理运算符重载以生成惰性对象评估。出于这个原因,operator +()的类不仅仅是存储传递类的引用以便稍后进行求值。

struct Base
{
     virtual void expensive_func()
     {
         throw "cant use this";
     };
     Composer operator+(int i)
     { 
          return Composer(*this, i);
     } 
}

struct Composer:public Base
{
    Base& refBase;
    int increment;
    virtual void expensive_func()
    {
        heavy_work();
    };     
    Composer(Base& a,int inc):
        refBase(a),increment(inc)
    {
    }
}


struct D:public Base
{
    ...
}

而不是问题arase

D a;
auto b = a + 2;
auto c = b + 3;
auto e = a + 3 + 4;

a.expensive_func(); //fine
b.expensive_func(); //fine
c.expensive_func(); //fine
e.expensive_func(); //segfault

解决方案是用

防止这种演习
operator+(const Coposer&&,int) = delete;  

但这只是阻止做我想做的事情

完整代码: - 我正在使用gcc / g ++ 4.8构建

#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>
#include <memory>

namespace Intervals
{
template <typename T>  struct ContainerMove; //forward declaration
template <typename T>
struct ContainerBase {
   typedef T mT;
  virtual T GetInterval (const T& val)
  {   
    throw; //overload this
  }

  T Integrate(const T& start = T(0))
  {
        T r(0);
        T next(start);
        while(1)
        {
            T i = GetInterval(next);
            if(i<0) //less that 0 is considered end  
            {
                return r;
            }
            r+=i;
            next=i;
        }
  }

  ContainerMove<T> operator +(const T& left);
  ContainerMove<T> operator -(const T& left);

  virtual ~ContainerBase(){};
};

//lazy container of ContainerBase
template <typename T>
struct ContainerMove:public ContainerBase<T>
{
    typedef ContainerBase<T> mConatinerBase;        
    const T mOffset;
    mConatinerBase& mIntervalSet; 

    ContainerMove(mConatinerBase& intervalset, const T& offset)
        :mOffset(offset),mIntervalSet(intervalset)
    {}

    virtual T GetInterval (const T& val)
    {
        auto i = mIntervalSet.GetInterval(val-mOffset);
        if(i < 0)
        {
            return T(-1000);
        }
        return T(i+mOffset);
    }
};
  template <typename T>
  ContainerMove<T> ContainerBase<T>::operator +(const ContainerBase<T>::mT& a)
  {
      return ContainerMove<T>(*this,a);  
  }

  template <typename T>
  ContainerMove<T> ContainerBase<T>::operator -(const ContainerBase<T>::mT& a)
  {
      return ContainerMove<T>(*this,-a);  
  }

  /*
  template <typename T>
  ContainerMove<T> operator +(const ContainerMove<T>&& , const typename ContainerBase<T>::mT&) = delete;
  template <typename T>
  ContainerMove<T> operator -(const ContainerMove<T>&& , const typename ContainerBase<T>::mT&) = delete;
  */
  template <class T>
struct Container:public ContainerBase<T>
{

    typedef Container<T> mThisType;
    typedef T mT;

    typedef  std::vector<T> SortedContainer_t;
    SortedContainer_t mContainer;

    template<class ForwardIter>
    Container(ForwardIter begin,ForwardIter end)
    :mContainer(begin,end)
    {
    }

    T GetInterval (const T& val)
    {
        auto r = std::upper_bound(mContainer.begin(), mContainer.end(),val);
        if (r == mContainer.end())
        {
            return T(-1000); //just as exeample <0 is ivalid value 
        }
        return *r;
    }
};
}

int main()
{
    typedef float T;
    typedef Intervals::Container<T> ContainerType;
    std::vector<T> v,u;
    const int N = 10;

    for(int i=0;i<N;++i)
    {
        v.push_back(T(i));
    }

    auto c = ContainerType(v.begin(),v.end());
    auto d=c+T(1);
    auto e=c+T(2)+T(3); //this yelds segmentation after e.Integrate()
    //std::cout << c.Integrate() << std::endl; 
    //std::cout << d.Integrate() << std::endl;
    std::cout << e.Integrate() << std::endl; //crash here

    return 0;
}

0 个答案:

没有答案