Полиморфный оператор в списке boost :: any? - PullRequest
2 голосов
/ 12 ноября 2010

Предположим, у меня есть список типа list<boost::any> с неизвестным типом.Теперь предположим, что я хочу применить некоторую операцию к элементам в списке, которая является полиморфной.В этом случае рассмотрим оператор +.Предположим, что я знаю, что список всегда будет содержать однородный набор объектов, поддерживающих оператор +, и я хочу получить результат применения оператора + (в некотором смысле «суммы») между каждым элементом списка в новый импульс:любой.Примерно так:

boost::any sum(list<boost::any> lst) {
    // return lst[0]+lst[1]+lst[2] etc
}

Не перечисляя все возможные типы, которые могут поддерживать оператор +, есть ли способ сделать это?Я чрезвычайно открыт для сумасшедших идей.

(у меня действительно есть веская причина для этого ... Я использую переводчика)

Ответы [ 3 ]

3 голосов
/ 12 ноября 2010

Вместо этого вы можете использовать boost::variant, если знаете диапазон возможных типов в списке.

Я не понимаю, как вы можете сделать это без сетки operator+ функций для обработки каждой возможной комбинации содержащихся типов или обычного полиморфизма во время выполнения.

Интересно, какой конкретный тип вы хотели бы видеть в окончательном выводе boost::any?

Кстати, если вы используете интерпретатор, посмотрите Boost.Spirit , который может осветить вашу проблему с дизайном здесь.

1 голос
/ 12 ноября 2010

Нет.Не с boost :: any и не с boost :: variable (не определяет ваше требование «Без перечисления всех возможных типов, которые могут поддерживать оператор +»).

Что вам нужно сделать, так это создать свое собственное.Концепция boost :: any довольно проста.Если вы посмотрите на документацию, у них есть ссылка на статью, объясняющую методику (в основном это идиома дескриптор / тело с полиморфизмом).Все, что вам нужно сделать, это решить, какой интерфейс должны иметь ваши различные объекты, и написать «любой» интерфейс, и это подразумевается соответственно.Нечто похожее на что-то вроде этого:

struct my_any
{
  template < typename T >
  my_any(T const& t) : pimpl(new impl<T>(t)) {}
  ...
  some_type get_some_type() const;
   ...
private:
  struct impl_base
  {
    ....
    virtual some_type get_some_type() const = 0;
  };
  template < typename T >
  struct impl : impl_base
  {
    some_type get_some_type() const { return t.get_some_type(); }
    impl(T const& t_var) : t(t_var) {}
    ....
  };
  boost::scoped_ptr<impl_base> pimpl;
};

some_type operator+ (my_any const& a, my_any const& b)
{
  return a.get_some_type() + b.get_some_type();
}

Трудно представить, что оператор + будет делать с универсальными типами, поэтому я придумал что-то, что имеет для меня небольшой смысл.Вам, конечно, нужно будет изменить свои потребности.

1 голос
/ 12 ноября 2010

C ++ сопоставляет функции (а операторы являются просто причудливыми функциями, имеющими дополнительный инфиксный синтаксис) по типам, а не по именам, во время компиляции . (Вместо проверки во время выполнения поддерживают ли вовлеченные объекты запрошенную операцию.)
Единственное исключение, о котором я могу думать, - это виртуальные функции. Если типы были полиморфными, вы могли бы использовать любой из обходных путей для пропуска мульти-методов (двойная диспетчеризация). Но так как они могут быть чем угодно, Я не думаю, что вы можете сделать это .

Если у вас ограниченный набор типов, шаблон-метапрограммирование может помочь сгенерировать функции, реализующие добавление. Но если бы количество задействованных типов было ограничено, вы, вероятно, использовали бы boost::variant.

(IME говорит, что это означает, что в очень короткое время кто-то приходит и доказывает, что я неправ.)

...