# Simple mathematical operations (add, sub, mul, div) in C++11 template

I made a simple script to implement basic mathematics operations by using variadic functions. I would like to know if my implementation is correct.

The code only works for Visual C++ compiler Nov 2013 CTP (CTP_Nov2013).

#include <iostream>
#include <string>
#include <exception>
using namespace std;

template <typename T>
{
return forward<T>(item);
}

template <typename T, typename ... Types>
auto add(T&& first, Types&& ... rest)
{
}

template <typename T>
T sub(T&& i = T())
{
return forward<T>(i);
}

template <typename T, typename ... Types>
auto sub(T&& first, Types&& ... rest)
-> decltype(forward<T>(first) - sub(forward<Types>(rest)...))
{
return forward<T>(first) - sub(forward<Types>(rest)...);
}

template <typename T>
T multiple(T&& i = T())
{
return forward<T>(i);
}

template <typename T, typename ... Types>
auto multiple(T&& first, Types&& ... rest)
-> decltype(forward<T>(first) * multiple(std::forward<Types>(rest)...))
{
return forward<T>(first) * multiple(forward<Types>(rest)...);
}

template <typename T>
T divide(T&& item = T())
{
return forward<T>(item);
}

template <typename T, typename ... Types>
auto divide(T&& first, Types&& ... rest)
-> decltype(forward<T>(first) / divide(forward<Types>(rest)...))
{
if (divide(forward<Types>(rest)...) == 0)
throw "Opps divided by Zero";
return forward<T>(first) / divide(forward<Types>(rest)...);
}

template<typename... Types>
void termnate(Types&&...)
{
std::cout << '\n';
}

template<typename... Types>
void result(Types&&... t)
{
termnate{ ([&]{ std::cout << forward<Types>(t) << ' '; }(), 1)... };
}

int main()
{
result(     add(1, 2.5, 3, 4, 5), " = ", "1 + 2,5 + 3 + 4 + 5");

result(sub(sub(sub(sub(1, 2.5), 3), 4), 5), " = ", "1 - 2.5 - 3 - 4 - 5"); // OK = -13.5

result(multiple(1, 2.5, 3, 4, 5), " = ", "1 x 2.5 x 3 x 4 x 5");

result(divide(divide(divide(divide(1, 2.5), 3), 4.5), 5), " = ", "1 / 2.5 / 3 / 4 / 5"); // OK = .005926

cout << add("\nTest ", "template: ", string("PASS\n"));
}

• Subtraction and division are not associative, so I am not sure how to define correctness of their variadic versions. Obviously, division by 0 returning 1 is wrong. – vnp Dec 10 '14 at 6:43
• @vnp ... yes, i was testing static_assert() but it won't be, i dunno why – MORTAL Dec 10 '14 at 6:50
• I'm fairly certain that you should be using forward when you pass on the && move references in the recursive calls. – glampert Dec 10 '14 at 13:31
• Don't forget to explicitly pass the template type (e.g.: std::forward<T>(x)), it can't figure out the type by itself otherwise. – glampert Dec 10 '14 at 13:36
• @glampert .. thanks that really deserve tobe an answer – MORTAL Dec 10 '14 at 13:53

When passing around move references, the recommended is to forward the parameters to ensure that the move reference is preserved:
template <typename T, typename ... Types>

Note that you have to explicitly provide the template type to std::forward(). It would deduce the wrong type otherwise.