#include #include #include using namespace std::string_literals; template auto sum(T final) { return final; } template auto sum(T first, Ts... rem) { return first + sum(rem...); } class ss_sum { std::stringstream ss; public: template ss_sum(T obj) : ss{} { ss << obj; } ss_sum(ss_sum const &rhs) : ss{} { std::string tmp; const_cast(rhs).ss >> tmp; const_cast(rhs).ss << tmp; ss << tmp; } ss_sum &operator=(ss_sum const &rhs) { std::string tmp; // clear out string stream ss >> tmp; const_cast(rhs).ss >> tmp; const_cast(rhs).ss << tmp; ss << tmp; return *this; } friend ss_sum operator+(ss_sum const &lhs, ss_sum const &rhs) { ss_sum ret = lhs; ss_sum tmp = rhs; std::string a; tmp.ss >> a; ret.ss << a; return ret; } friend bool operator==(ss_sum const &lhs, ss_sum const &rhs) { ss_sum inner_l = lhs; ss_sum inner_r = rhs; std::string l; std::string r; inner_l.ss >> l; inner_r.ss >> r; return l == r; } }; int main(void) { bool dummy = sum(1.5, 2, 3, 10) == 16.5; assert(dummy); dummy = sum(1, 5, 7, 8, 2, 3, 4) == 30; assert(dummy); dummy = sum(1.5, 1, 2, 3.5) == 8.0; assert(dummy); dummy = sum("asdf"s, "abcdefghijklmnop"s, "qrstuvwxyz"s) == "asdfabcdefghijklmnopqrstuvwxyz"s; assert(dummy); // ss_sum is only associative when everything is ss_sum auto tmp = sum(1, 2, 3); dummy = tmp == ss_sum{"123"}; assert(dummy); // demo of situation where associativity isn't applicable ss_sum+(int+int) != // (ss_sum+int)+int tmp = sum(1, 2, 3); dummy = tmp == ss_sum{"15"}; assert(dummy); }