这是 C++ Primer 第 16.2.3 章(问题 16.41)中的一个问题:
Write a version of sum with a return type that is guaranteed to be large enough to hold the result of the addition.
我确信可能有一些相当晦涩的 STL 函数可以完成这项工作,但在本章的上下文中它介绍了标准类型转换模板,例如 remove_reference<T>
和 make_signed<T>
我确定它打算让我结合尾随返回类型来完成此操作。我能做的最好的是:
template <typename It> auto sum(It first, It second) -> typename make_unsigned<It>::type {
return first+second;
}
这几乎回答了问题但不完全是,它没有说明我可以通过两个 unsigned int
的事实添加到超出 unsigned int
的值范围的 s可以保持(因此循环回到零)。据我所知,转换模板无法帮助解决这个问题,是否有可能从传递的参数推导出的整数类型中推断出返回类型作为下一个最大的整数类型?
最佳答案
由于您想在编译时执行此操作,因此无法知道将调用该函数的参数值。所以你应该在编译时防止溢出,我想到的最明显的事情是使用提升特征类:
#include <iostream>
#include <limits>
template<typename T>
struct promote;
template<> // and so on for all types that you want to promote
struct promote<unsigned int> // type to be promoted from
{
using type = unsigned long int; // type to be promoted to
};
// helper a la C++14
template<typename T>
using promote_t = typename promote<T>::type;
template <typename It>
auto my_sum(It first, It second) -> promote_t<It>
{
return static_cast<promote_t<It>>(first) + second; // promotion
}
int main()
{
unsigned int a = std::numeric_limits<unsigned int>::max();
unsigned int b = std::numeric_limits<unsigned int>::max();
auto c = my_sum(a, b); // type is promoted to unsigned long int
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;
std::cout << "a + b = " << c << std::endl;
}
关于c++ - 返回类型足够大以保存结果的 Sum 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33640144/