(This question has been dramatically edited from the original, without changing the real intent of the original question)
If we add up all the elements in a vector<int>
, then the answer could overflow, requiring something like intmax_t
to store the answer accurately and without overflow. But intmax_t
isn't suitable for vector<double>
.
I could manually specify the types:
template<typename>
struct sum_traits;
template<>
struct sum_traits<int> {
typedef long accumulate_safely_t;
};
and then use them as follows:
template<typename C>
auto sum(const C& c) {
sum_traits<decltype(c.begin())> :: accumulate_safely_t> r = 0;
for(auto &el: c)
r += el;
return r;
}
My questions: Is it possible to automatically identify a suitable type, a large and accurate type, so I don't have to manually specify each one via the type trait?
You can use return type deduction in C++14 just like this:
template<typename C>
auto sum(const C& c) {
auto r = 0;
for(auto &el: c)
r += el;
return r;
}
In C++11, considering your C++98 code, you may use the following:
template<typename C>
auto sum(const C& c) -> typename C::value_type {
auto r = 0;
for(auto &el: c)
r += el;
return r;
}
But, as pointed in the comments, auto r = 0;
will still resolve to int
at compile time. As proposed in an other answer, you may want to make the initial value type (and so the return value type) a template parameter as well:
template<typename C, typename T>
T sum(const C& c, T init) {
for(auto &el: c)
init += el;
return init;
}
// usage
std::vector<std::string> v({"Hello ", "World ", "!!!"});
std::cout << sum(v, std::string{});