#include #include #include #include #include #include template auto add(T const& a, U const& b); template auto add_helper(T const& a, U const& b, int, int) -> decltype( a + b ) { return a + b; } template auto add_helper(T const& a, U const& b, int, float) -> decltype( std::begin(a), std::begin(b), T{a} ) { T result { a }; auto it = std::begin(b); for (auto& element : result) element = add(element, *it++); return result; } template auto add_helper(T const& a, U const& b, float, float) -> decltype( std::begin(a), T{a} ) { T result { a }; for (auto& element : result) element = add(element, b); return result; } template auto add(T const& a, U const& b) { return add_helper(a, b, 0, 0); } int main() { // Try some basic things assert(( add(1, 2) == 3 )); assert(( add(1.5, 2) == 3.5 )); assert(( add(1.5, 2.5) == 4.0 )); // Try with all vectors { std::vector v1 { 1, 2, 3 }; std::vector v2 { 4, 5, 6 }; std::vector v3 { 5, 7, 9 }; assert(( add(v1, 3) == v2 )); assert(( add(v1, v2) == v3 )); } // Mix-up the containers { std::list v1 { 1, 2, 3 }; std::list v2 { 4, 5, 6 }; std::list v3 { 5, 7, 9 }; std::set v4 { 4, 5, 6 }; std::vector v5 { 3, 3, 3 }; assert(( add(v1, 3) == v2 )); assert(( add(v1, v4) == v3 )); assert(( add(v1, v5) == v2 )); } // test strings (which overlap with case #1 and case #2) { std::string str1 { "abc" }; std::string str2 { "def" }; // Should be case #1 assert(( add(str1, str2) == "abcdef" )); } { std::vector v1 { "a", "b", "c" }; std::vector v2 { "a1", "b2", "c3" }; std::string s1 { "123" }; // should land in case #2 assert(( add(v1, s1) == v2 )); } }