Я столкнулся с ситуацией, когда порядок перегрузок функций имеет значение.Я думал, что причиной должна быть часть SFINAE с std::enable_if
((я дополнительно протестировал код без std::enable_if
, только с шаблонами, а затем код выполняется независимо от порядка перегрузок функций.))
Я сделал из этого минимальный рабочий пример.
Этот кодовый блок работает
#include <type_traits>
template <bool C, typename R = void>
using EnableIf = typename std::enable_if<C, R>::type;
template <typename T, typename R = void>
using IfIsArithmetic = EnableIf<std::is_arithmetic<T>::value, R>;
template <typename S>
IfIsArithmetic<S, void> Add(S const &scalar1, S const &scalar2, S &ret)
{
ret = scalar1 + scalar2;
}
template <typename S>
IfIsArithmetic<S, S> Add(S const &scalar1, S const &scalar2)
{
S ret;
Add(scalar1, scalar2, ret);
return ret;
}
using T = float;
int main(){
T a = 3.1;
T b = 3.5;
T c{Add(a, b)};
}
, тогда как следующее не компилируется (реализации функций Add()
меняются местами)
#include <type_traits>
template <bool C, typename R = void>
using EnableIf = typename std::enable_if<C, R>::type;
template <typename T, typename R = void>
using IfIsArithmetic = EnableIf<std::is_arithmetic<T>::value, R>;
template <typename S>
IfIsArithmetic<S, S> Add(S const &scalar1, S const &scalar2)
{
S ret;
Add(scalar1, scalar2, ret);
return ret;
}
template <typename S>
IfIsArithmetic<S, void> Add(S const &scalar1, S const &scalar2, S &ret)
{
ret = scalar1 + scalar2;
}
using T = float;
int main(){
T a = 3.1;
T b = 3.5;
T c{Add(a, b)};
}
Компилятор выдает следующую ошибку
test.cpp: In instantiation of ‘IfIsArithmetic<S, S> Add(const S&, const S&) [with S = float; IfIsArithmetic<S, S> = float]’:
test.cpp:28:15: required from here
test.cpp:13:5: error: no matching function for call to ‘Add(const float&, const float&, float&)’
Add(scalar1, scalar2, ret);
~~~^~~~~~~~~~~~~~~~~~~~~~~
test.cpp:10:22: note: candidate: template<class S> IfIsArithmetic<S, S> Add(const S&, const S&)
IfIsArithmetic<S, S> Add(S const &scalar1, S const &scalar2)
^~~
test.cpp:10:22: note: template argument deduction/substitution failed:
test.cpp:13:5: note: candidate expects 2 arguments, 3 provided
Add(scalar1, scalar2, ret);
~~~^~~~~~~~~~~~~~~~~~~~~~~
Кажется, что компилятор пытается использовать перегрузку первой функции, даже если подпись не выравнивается.
Может быть, некоторые из вас подскажут, с каким правилом поиска функции C ++ связана эта проблема!