#include <utility> template<typename T, typename U> constexpr auto multiply(T a, U b) -> decltype(std::declval<T>() * std::declval<U>()){ return a * b; }
#define multiply(a,b) a*b- #include <utility>
- template<typename T, typename U>
- constexpr auto multiply(T a, U b) -> decltype(std::declval<T>() * std::declval<U>()){
- return a * b;
- }
I know this doesn't work in the current c+ version. Needs c++20.
But with concepts, some of this can be simplified
Concept to check if T + T is valid.
Concept to check if U(T + T) + T is valid, and is U.
T + T could give a different type U, but T + U must be U again.
/* #include <concepts> #include <vector> #include <numeric> #include <type_traits> namespace{ // Concept to check if T + T yields a valid type template <typename T> concept SelfAddable = requires(T a) { { a + a }; // Ensure T + T is valid }; // Concept to check if U + T is valid and results in U template <typename T, typename U> concept CompatibleAddable = requires(U u, T t) { { u + t } -> std::same_as<U>; }; // Function template with inferred U template <SelfAddable T> requires CompatibleAddable<T, decltype(std::declval<T>() + std::declval<T>())> auto sum(const std::vector<T>& v) { using U = decltype(std::declval<T>() + std::declval<T>()); // Infer U return std::accumulate(v.cbegin(), v.cend(), U{}, [](U acc, const T& elem) { return acc + elem; }); } } */ //OLD #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 <concepts>
- #include <vector>
- #include <numeric>
- #include <type_traits>
- namespace{
- // Concept to check if T + T yields a valid type
- template <typename T>
- concept SelfAddable = requires(T a) {
- { a + a }; // Ensure T + T is valid
- };
- // Concept to check if U + T is valid and results in U
- template <typename T, typename U>
- concept CompatibleAddable = requires(U u, T t) {
- { u + t } -> std::same_as<U>;
- };
- // Function template with inferred U
- template <SelfAddable T>
- requires CompatibleAddable<T, decltype(std::declval<T>() + std::declval<T>())>
- auto sum(const std::vector<T>& v) {
- using U = decltype(std::declval<T>() + std::declval<T>()); // Infer U
- return std::accumulate(v.cbegin(), v.cend(), U{}, [](U acc, const T& elem) {
- return acc + elem;
- });
- }
- }
- */
- //OLD
- #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{});
- }
- }