c++ - 返回类型足够大以保存结果的 Sum 函数

标签 c++ templates c++11 sum

这是 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;
}

Live on Coliru

关于c++ - 返回类型足够大以保存结果的 Sum 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33640144/

相关文章:

c++ - 我能知道转换中匹配 boost::proto::_ 的类型吗?

c++ - 构建通用重载运算符<<

c++ - 为什么这个函数模板调用有效?

c++ - 我们应该在何时何地使用编译时宏连接?

c++ - 使用 C++ 和 OpenCV 将 RGB 转换为 LMS 模型

c++ - 接受指针参数的 GCC 纯/常量函数

c++ - 链表类内存泄漏

c++ - C++ 中的 Lambda 通用性

c++ - std::bind 与来自父类的重载函数

c++ - 是否可以从现有基类动态分配派生类所需的额外内存?