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>
T add(T&& item = T())
{
return forward<T>(item);
}
template <typename T, typename ... Types>
auto add(T&& first, Types&& ... rest)
-> decltype(first + add(forward<Types>(rest)...))
{
return forward<T>(first) + add(forward<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"));
}
forward
when you pass on the&&
move references in the recursive calls. \$\endgroup\$ – glampert Dec 10 '14 at 13:31std::forward<T>(x)
), it can't figure out the type by itself otherwise. \$\endgroup\$ – glampert Dec 10 '14 at 13:36