Перегрузка оператора вне класса шаблона неявными преобразованиями
у меня есть класс шаблона, определенный следующим образом
template<class T> class Wrap
{
/* ... */
public:
Wrap(const T&);
/* other implicit conversions */
/* ... */
};
Я хочу, чтобы определить все операторы сравнения для этого класса вне класса, как это
template<typename T> bool operator == (const Wrap<T>&, const Wrap<T>&)
{
// Do comparison here
}
однако это объявление не поддерживает неявные преобразования const T&
, или любой другой тип, к const Wrap<T>&
.
поэтому мой вопрос в том, как я могу сделать его поддержкой неявных преобразований, когда любой из операндов имеет тип Wrap<T>
а другой нет. Я не хочу писать несколько объявления каждого оператора для каждой возможной перестановки.
2 ответов
template<class T> struct is_wrap : std::false_type {};
template<class T> struct is_wrap<Wrap<T>> : std::true_type {};
template<class T1, class T2> typename std::enable_if<is_wrap<typename std::common_type<T1, T2>::type>::value, bool>::type operator == (const T1& t1, const T2& t2)
{
const typename std::common_type<T1, T2>::type& tc1 = t1, tc2 = t2;
// compare with tc1 and tc2
}
кто-то другой сформулирует это лучше, но я думаю, что проблема в том, что компилятор не может вывести T
на Wrap<T>
без вас проходя его Wrap
"объект". Я думаю, что ваша ситуация должна быть решена, если вы явно даете operator==
аргумент шаблона: operator==<int>(7, 4)
, например, должен работать.
у меня нет компилятора передо мной, но вот моя попытка:
template<typename T>
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const Wrap<T>& l, const T& r)
{
return l.stuff == Wrap<T>(r).stuff;
}
template<typename T>
typename std::enable_if<std::is_convertible<Wrap<T>, T>::value, bool>::type operator==(const T& l, const Wrap<T>& r)
{
return r == l; // call above operator
}
это должно работать, если любая из сторон является Wrap
а другая сторона-нет. Ты мог бы ... также сделайте обе стороны как const T&
, однако, если Wrap
действительно неявно конструируется из любого T
вы закончите с помощью вашего operator==
для многих непреднамеренных сравнений, даже int
s,string
s, etc.