Слабосвязанное неявное преобразование

Неявное преобразование может быть действительно полезным, когда типы семантически эквивалентны. Например, представьте две библиотеки, которые идентично реализуют тип, но в разных пространствах имен. Или просто тип, который в основном идентичен, за исключением некоторого семантического сахара здесь и там. Теперь вы не можете передать один тип в функцию (в одной из этих библиотек), которая была разработана для использования другого, если эта функция не является шаблоном. Если это не так, вам нужно как-то преобразовать один тип в другой. Это должно быть тривиально (иначе все-таки типы не так уж идентичны! ), но вызов преобразования явно раздувает ваш код в основном бессмысленными вызовами функций. Хотя такие функции преобразования могут фактически копировать некоторые значения, они по существу ничего не делают с точки зрения высокоуровневых «программистов».

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

Теперь я вижу два варианта того, как заставить работать неявное преобразование в пользовательском коде:

  1. Первый - предоставить прокси-тип, который реализует операторы преобразования и преобразование- конструкторы (и присваивания) для всех задействованных типов и всегда их используют. Добавьте конструктор преобразования для каждого задействованного типа, который может быть дополнительно включен извне.

Например, для типа A добавьте конструктор:

template <class T> A(
  const T& src,
  typename boost::enable_if<conversion_enabled<T,A>>::type* ignore=0
)
{
  *this = convert(src);
}

и шаблон

template <class X, class Y>
struct conversion_enabled : public boost::mpl::false_ {};

, который отключает неявное преобразование по умолчанию.

Затем, чтобы включить преобразование между двумя типами, настройте шаблон:

template <> struct conversion_enabled<OtherA, A> : public boost::mpl::true_ {};

и реализуйте функцию convert , которую можно найти через ADL.

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

Теперь перейдем к собственно вопросу (ам): Какой предпочтительный способ ассоциировать типы для неявного преобразования? Мои предложения хорошие идеи? Есть ли недостатки у любого подхода? Опасно ли разрешать подобные преобразования? Должны ли разработчики библиотеки в целом предоставлять второй метод, когда он Скорее всего, их тип будет воспроизведен в программном обеспечении, с которым они, скорее всего, будут использоваться (здесь я имею в виду промежуточное ПО для 3D-рендеринга, где большинство этих пакетов реализуют 3D-вектор).

25
задан ltjax 15 January 2011 в 20:37
поделиться