返回类型足够大以保存结果的求和函数 [英] Sum function with return type large enough to hold result

查看:98
本文介绍了返回类型足够大以保存结果的求和函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是C ++ Primer第16.2.3章中的一个问题(问题16.41):

It's a question from C++ Primer Chapter 16.2.3 (question 16.41):


写一个sum版本,其返回类型为是
保证足够大以容纳加法的结果。

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> ,我确定它打算与跟踪返回类型一起用于完成此任务。我能做的最好的事情是:

I'm sure there might be some rather obscure STL function that can get this job done, but in the context of the chapter it introduces Standard Type Transformation Templates such as remove_reference<T> and make_signed<T> which I'm sure it intends for me to use to accomplish this, in conjunction with trailing return types. The best I can do is:

template <typename It> auto sum(It first, It second) -> typename make_unsigned<It>::type {
    return first+second;
}

这几乎可以回答问题,但不能完全解决,不能解释这个问题我可以传递两个 unsigned int 的事实,这些值超出了 unsigned int 可以容纳的值范围(因此循环回零)。据我所知,转换模板无助于解决该问题,是否可以通过传递的参数推导的整数类型将返回类型推论为第二大整数类型?

This almost answers the question but not quite, it doesn't account for that fact that I could pass two unsigned ints which add to go outside the range of values that an unsigned int can hold (and so loops back down to zero). As far as I can tell the transformation templates can't help with that issue, is it somehow possible to deduce the return type as the next largest integral type up from the integral type deduced from the passed arguments?

推荐答案

由于要在编译时执行此操作,因此无法知道将调用该函数的参数的值。因此,您应该在编译时防止再次溢出,并且我想到的最明显的事情是使用了升级特质类:

Since you want to do this at compile time, there is no way of knowing the value of the arguments the function will be invoked with. So you should protect agains overflowing at compile time, and the most obvious thing that comes to my mind is using a promotion trait class:

#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;
}

在Coliru上直播

这篇关于返回类型足够大以保存结果的求和函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆