Перегруженные операторы, наследование и шаблоны (грозная комбинация)

Приветствую всех.

Я пишу код с использованием библиотеки Boost Units и столкнулся с проблемой.

Мне удалось абстрагировать проблему из кода Boost, поэтому вы не будете просматривать пачки мета-программирования ускоренных шаблонов. Хотя я уверен, что если у вас есть в этом опыт, это может помочь. Вот воспроизведение:

class Base{};
class Derived : public Base
{
public:
  Derived(){}
  Derived(const Base &){}
};

class Q {};
class U
{
public:
  template< typename Y >
  Q operator * (Y)
  {
    Q r;
    return r;
  }
};

Base operator * (U, const Base &)
{
  Base r;
  return r;
}

int main(int argc, char **argv)
{
  Base myBase;
  U myU;
  Base myOtherBase = myU * myBase;
  Derived myDerived;
  Derived myOtherDerived =  myU * myDerived;
  return 0;
}

Итак, проблема (в частности) заключается в следующем: myU * myBase использует оператор * (U, const Base &) и возвращает тип База , пока все хорошо. В то время как myU * myDerived настаивает на использовании обобщенного U :: operator * (Y) и, следовательно, возвращает Q , это бесполезно, потому что я хотел Base снова.

Теперь, все классы, кроме Base и Derived , являются расширенными библиотечными классами, поэтому я не могу изменять члены U. Как мне «превзойти» U :: operator * (Y) для перегрузки / вывода шаблонов / создания экземпляров, в данном случае элегантным и «решенным раз и навсегда» способом.

Я использую MSVC ++ 2008 на случай, если он кому-то нужен.

Изменить: добавлен возможное (вполне вероятное) решение в ответах

7
задан EdF 14 May 2011 в 12:31
поделиться