Ad

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.

Code
Diff
  • #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{});
    • }
    • }