Если вы можете использовать C ++ 17, вы можете использовать auto
для M
значение
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
Таким образом, вы можете назвать его следующим образом
add<32>(a);
До C++ 17 ... ну, я не вижу пути без объяснения также типа.
Как указывает Jarod42, auto M
перехватывает также значения разных типов.
Если выхотите навязать, что тип M
равен точно T
, вы можете использовать SFINAE;Например, следующим образом:
template <auto M, typename T, T N,
std::enable_if_t<std::is_same_v<T, decltype(M)>, bool> = true>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
Таким образом, вы получаете ошибки от
add<32u>(a);
add<short{32}>(a);
Но, возможно, вы можете ослабить требование и принять также, что decltype(M)
не совсем T
, нотакже просто, что M
сужается, преобразуется в T
.
Возможно
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + T{M}>();
} // .......................^^^^
, поэтому
add<32u>(a);
add<short{32}>(a);
скомпилированы, потому что 32u
и short{32}
конвертируемо в int
, где
add<(unsigned long)(-1)>(a);
дает ошибку компиляции, потому что (unsigned long)(-1)
(обычно большее возможное значение для unsigned long
) не может быть сужено до int
.