После еще нескольких работ я наконец-то заметил, что случилось.Сначала мне удалось повторить ошибку на gcc здесь .Когда я начал больше думать об этом, я наконец обнаружил это.В clamped_value
есть макрос:
#define GEN_ARITHMETIC_OP(op) \
template<typename Ty, Ty TMin, Ty TMax, typename U, U UMin, U UMax> \
friend constexpr detail::common_clamped_value_t<Ty, TMin, TMax, U, UMin, UMax> \
operator op(clamped_value<Ty, TMin, TMax> const& lhs, clamped_value<U, UMin, UMax> const& rhs) \
{ \
auto val = detail::common_clamped_value_t<Ty, TMin, TMax, U, UMin, UMax>(lhs.m_value op rhs.m_value); \
val.clamp(); \
return val; \
}
Теперь проблема в том, что первый clamped_value
является шаблонным и, таким образом, работает для всех clamped_value
.Поэтому, если я создаю экземпляр только одного clamped_value
, все работает.Но с того момента, как я использую новый набор параметров шаблона, макрос снова раскрывается , и оператор определяется дважды.Простым решением было изменить определение макроса, чтобы оно работало только для текущего экземпляра типа:
#define GEN_ARITHMETIC_OP(op) \
template<typename U, U UMin, U UMax> \
friend constexpr detail::common_clamped_value_t<T, Min, Max, U, UMin, UMax> \
operator op(clamped_value const& lhs, clamped_value<U, UMin, UMax> const& rhs) \
{ \
auto val = detail::common_clamped_value_t<T, Min, Max, U, UMin, UMax>(lhs.m_value op rhs.m_value); \
val.clamp(); \
return val; \
}