Шаблон C ++: оператор перегрузки +, а тип возвращаемого значения определяется типом ввода - PullRequest
2 голосов
/ 06 марта 2012

Предположим, у меня есть следующий класс

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 ]

5 голосов
/ 06 марта 2012

Просто вычислите ваш новый тип в операторе + тип возвращаемого значения и используйте 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;
}

Теперь обратите внимание, насколько это громоздко.Обычной идиомой в этом случае является использование интегральных типов 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авто.Еще одна классическая вещь - сделать это функциональным объектом по протоколу result_of, чтобы у вас была удобная мета-функция для непрозрачного вычисления возвращаемого типа.

1 голос
/ 06 марта 2012

Попробуйте это:

#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";
}
1 голос
/ 06 марта 2012

Я думаю, что это возможно, возможно, используя повышение MPL [1].

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

1 голос
/ 06 марта 2012

Я думаю, вы ищете что-то вроде этого.

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;
    }

, а затем перегрузите оператор =, и вы сможете выполнить желаемую операцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...