Я создаю operator+
, используя функцию шаблона для иерархии типов. Первая простая попытка работала нормально, пока я не попытался объединить строку в другой части кода, и GCC 8.3 попытался использовать мой operator+
.
Попытка использовать enable_if
и is_base_of
, чтобы ограничить мою версию моими типами, чтобы SFINAE справился с этой проблемой.
Одна попытка среди многих:
template < //
typename T1, //
typename T2, typename std::enable_if_t<std::is_base_of_v<LogicGateAbs, T2>, T2> //
>
inline OrGate operator +(T1&& lhs, T2&& rhs) {
return OrGate { LogicGateAbs::make_concrete(lhs), LogicGateAbs::make_concrete(rhs) };
}
Здесь компилятор правильно указывает типы:
./src2/test.cpp:90:11: error: no match for ‘operator+’ (operand types are ‘TrueGate’ and ‘TrueGate’)
(True + True);
~~~~~^~~~~~
Но почему тогда он возвращает 'false' для is_base_of
, поскольку LogicGateAbs
является основой TrueGate
?
../src2/test.cpp:83:15: note: candidate: ‘template<class T1, class T2, typename std::enable_if<is_base_of_v<LogicGateAbs, T2>, T2>::type <anonymous> > OrGate operator+(T1&&, T2&&)’
inline OrGate operator +(T1&& lhs, T2&& rhs) {
^~~~~~~~
../src2/test.cpp:83:15: note: template argument deduction/substitution failed:
../src2/test.cpp:81:32: error: no type named ‘type’ in ‘struct std::enable_if<false, TrueGate&>’
typename T2, typename std::enable_if_t<std::is_base_of_v<LogicGateAbs, T2>, T2> //
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Перебрал каждую его версию в StackOverflow, не заставляя работать версию.
Базовая функция работает по мере необходимости. Ссылка на rvalue необходима, поскольку входные данные часто являются временными значениями.