C ++模板:重载operator +,而返回类型由输入类型决定

时间:2012-03-06 06:00:54

标签: c++ templates operator-overloading

假设我有以下课程

template<unsigned char B, unsigned char F>
class Foo
{
   .....
}

我希望重载运算符+,以便两个输入都是

Foo<B1, F1> 

Foo<B2, F2>, 

分别我希望返回值是

的类型
Foo<max(B1, B2), max(F1, F2)>. 

或类似

Foo<max(B1-F1, B2-F2)+max(F1, F2), max(F1, F2)>. 

任何提示?

4 个答案:

答案 0 :(得分:5)

只需在operator + return类型中计算新类型,并使用MPL进行比较 此外,您不需要朋友,因为您的运营商+都不需要是可变的。

简单类的简单示例:

#include <boost/mpl/max.hpp>

template<unsigned char B, unsigned char F>
class Foo
{};

template< unsigned char B1, unsigned char F1
        , unsigned char B2, unsigned char F2
        >
Foo< boost::mpl::max_<boost::mpl_::char_<B1>, boost::mpl_::char_<B2> >::value
   , boost::mpl::max_<boost::mpl_::char_<F1>, boost::mpl_::char_<F2> >::value
   >
operator+(Foo<B1,F1> const& a, Foo<B2,F2> const& b)
{
  Foo< boost::mpl::max_<boost::mpl_::char_<B1>, boost::mpl_::char_<B2> >::value
   , boost::mpl::max_<boost::mpl_::char_<F1>, boost::mpl_::char_<F2> >::value
   > that;
  return that;
}

现在,请注意它是多么麻烦。在这种情况下,通常的习惯是尽可能使用Boost MPL积分类型而不是原始值

#include <boost/mpl/max.hpp>

template<class B, class F>
class Foo
{};

template< class B1, class F1
        , class B2, class F2
        >
Foo< typename boost::mpl::max_<B1, B2>::type
   , typename boost::mpl::max_<F1, F2>::type
   >
operator+(Foo<B1,F1> const& a, Foo<B2,F2> const& b)
{
   Foo< typename boost::mpl::max_<B1, B2>::type
      , typename boost::mpl::max_<F1, F2>::type
      > that;
  return that;
}

Foo< boost::mpl::int_<4>, boost::mpl::int_<8> > x;

编辑: 此外,这使得在pre_C ++ 11 auto中写入的返回类型有点复杂。 另一个经典的东西是将它变成一个遵循result_of协议的函数对象,这样你就可以使用元函数以不透明的方式计算返回类型。

答案 1 :(得分:1)

我猜你正在寻找这样的东西。

foo a,b,c;
a = b + c;

为此,您还需要重载'='运算符。

enter code here
    template <typename t,typename f>
    foo& operator + (const foo& source)
    {
        //add the date members
        return *this;
    }

然后重载=运算符,你应该能够实现所需的操作。

答案 2 :(得分:1)

我认为这是可能的,也许是使用boost MPL [1]。

[1] http://www.boost.org/doc/libs/1_49_0/libs/mpl/doc/index.html

答案 3 :(得分:1)

试试这个:

#include <algorithm>
#include <iostream>

template <unsigned char A, unsigned char B>
struct max {
  enum { value = A>B ? A : B};
};

template <unsigned char B, unsigned char F>
class Foo {};

template <unsigned char B, unsigned char F>
std::ostream&
operator<<(std::ostream& os, Foo<B, F>) {
  return os << "Foo<" << (int)B << "," << (int)F << ">";
}

template <unsigned char B1, unsigned char F1,
          unsigned char B2, unsigned char F2>
Foo<max<B1, B2>::value, max<F1, F2>::value>
operator+( const Foo<B1, F1>&, const Foo<B2, F2>& )
{
  return Foo<max<B1, B2>::value, max<F1, F2>::value>();
}

int main() {
  Foo<1,3> foo13;
  Foo<0,4> foo04;

  std::cout << foo13 << "\n";
  std::cout << foo04 << "\n";
  std::cout << foo13 + foo04 << "\n";
}