This algorithm of 'sum()' is SFINAE-friendly. By first testing if the corresponding types can be added with the type trait 'has_plus' because some types doesn't have the 'operator+' defined. If for any reason, the types doesn't have the addition operator available, the function will be disabled via 'std::enable_if' and will be discarded by SFINAE. In constrast, if the types can be added, the 'std::enable_if' trait will enable the function and returning the corresponding type of add the two types with the 'plus_result' trait.
#include <vector> #include <numeric> #include <type_traits> #include <utility> namespace { template<typename, typename, typename = void> struct has_plus : std::false_type {}; template<typename T1, typename T2> struct has_plus<T1, T2, std::void_t<decltype(std::declval<T1>() + std::declval<T2>())>> : std::true_type {}; template<typename T1, typename T2> inline constexpr bool has_plus_v = has_plus<T1, T2>::value; template<typename T1, typename T2, bool = has_plus_v<T1, T2>> struct plus_result { using type = decltype(std::declval<T1>() + std::declval<T2>()); }; template<typename T1, typename T2> struct plus_result<T1, T2, false> {}; template<typename T1, typename T2> using plus_result_t = typename plus_result<T1, T2>::type; template<typename T = double, typename = std::enable_if_t<has_plus_v<T, T>>> plus_result_t<T, T> sum(const std::vector<T>& v) { return std::accumulate(v.cbegin(), v.cend(), T{}); } }
- #include <vector>
- #include <numeric>
- #include <type_traits>
- #include <utility>
template <typename T> using add_t=decltype(T() + T());- namespace
- {
- template<typename, typename, typename = void>
- struct has_plus : std::false_type {};
template <typename T = double>add_t<T> sum(const std::vector<T>& v) {return std::accumulate(v.cbegin(),v.cend(),add_t<T>{0});- template<typename T1, typename T2>
- struct has_plus<T1, T2, std::void_t<decltype(std::declval<T1>() + std::declval<T2>())>> : std::true_type {};
- template<typename T1, typename T2>
- inline constexpr bool has_plus_v = has_plus<T1, T2>::value;
- template<typename T1, typename T2, bool = has_plus_v<T1, T2>>
- struct plus_result
- {
- using type = decltype(std::declval<T1>() + std::declval<T2>());
- };
- template<typename T1, typename T2>
- struct plus_result<T1, T2, false> {};
- template<typename T1, typename T2>
- using plus_result_t = typename plus_result<T1, T2>::type;
- template<typename T = double, typename = std::enable_if_t<has_plus_v<T, T>>>
- plus_result_t<T, T> sum(const std::vector<T>& v)
- {
- return std::accumulate(v.cbegin(), v.cend(), T{});
- }
- }