2

Учитывая следующий код:Экспресс предпочтение в случае неоднозначных шаблонных функций

struct Zero{}; 

template<typename T> 
Zero operator*(const Zero& zero, const T& other){return Zero();} 

struct Identity{}; 

template<typename T> 
T operator*(const T& other, const Identity& id){return T();} 

Теперь я хочу использовать этот код, как это:

Zero z; 
Identity id; 
int i = 5; 
z * i; // ok 
i * id; // ok 
z * id; //error: ambiguity in function resolution 

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

Вопрос: Как я могу выразить, что в этом случае любая из функций в порядке?

+0

BTW: Вы могли бы хотите взглянуть на 'constexpr'. – Deduplicator

ответ

3

Просто добавьте еще одну перегрузку (которая не является шаблоном вообще):

Zero operator*(const Zero& other, const Identity& id){return Zero();} 
+0

Это также работает. +1 – Deduplicator

2

Просто используйте SFINAE удалить первый шаблон из рассмотрения, если T является Identity:

template<typename T> auto operator*(const Zero& zero, const T& other) 
-> typename std::enable_if<!std::is_same<T, Identity>::value, Zero>::value 
{return {};} 
+0

Мне нравится этот ответ. Хотя это делает код более запутанным, предпочтительнее, когда я начинаю иметь разные версии оператора * (например, когда шаблоны «Идентичность» или «Нуль»). В предыдущем ответе мне пришлось бы дублировать код. Большое спасибо! – Alex