模板函数怎么防止溢出?

bandaoyu 2019-03-18 03:35:55
例如:

template <class T>
T add(const T lva, const T rva)
{
long a = lva + rva;
return a;
}


template <class T>
T mult(const T lva, const T rva)
{
long a = lva * rva;
return a;
}


int a = 0;
int b = 0;
long c = 0;


c = add(a,b);
c = mult(a,b)

要是a + b > int / a*b > int 的最大值怎么办? 你们是怎么防止溢出错误的
...全文
514 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2019-04-30
  • 打赏
  • 举报
回复
我的意思是说,即使用模板,仍然解决不了溢出问题。
赵4老师 2019-04-29
  • 打赏
  • 举报
回复
在现实世界中,除时间和空间可能是无限的以外,其它任何事物都是有限的。
jiht594 2019-04-29
  • 打赏
  • 举报
回复
引用 17 楼 bandaoyu 的回复:
引用 16 楼 jiht594 的回复:
哦~~ 也就是说 语言层面是干不了这事的 最终还是要靠人的自觉和意识对吧

不能叫靠自觉。
比如说内部数据、你知道它的取值范围。 比如你要统计全国人口、要把各个省市人加起来。你知道总人数十几亿、放宽点全球人数也不到100亿。这样你的数据最大值要满足十几亿或者100亿。

如果外部数据、你就要限制一下、判断数据是否合法。不能统计时、用户输入个1000亿、你还继续往下算。

这个东西应该编码之前就考虑好。
bandaoyu 2019-04-29
  • 打赏
  • 举报
回复
引用 16 楼 jiht594 的回复:
哦~~ 也就是说 语言层面是干不了这事的 最终还是要靠人的自觉和意识对吧
jiht594 2019-04-29
  • 打赏
  • 举报
回复
引用 14 楼 bandaoyu 的回复:
引用 12 楼 weixin_44749415 的回复:
楼主自己看看,ini*int是什么类型?
楼上说了 还是int类型 如果溢出了 结果就不正确了,一般你们 int*int 用什么类型接?


既然可能溢出。 说明定义为int,不太合适。 可以定义为long 或者long long。如果还是一处、使用大数类。
这个东西需要设计来保证。
bandaoyu 2019-04-29
  • 打赏
  • 举报
回复
引用 20 楼 早打大打打核战争 的回复:

所噶!
bandaoyu 2019-04-29
  • 打赏
  • 举报
回复
引用 19 楼 赵4老师 的回复:
在现实世界中,除时间和空间可能是无限的以外,其它任何事物都是有限的。
机器人又来了。老大不知道去哪里了最近,老师放出机器人来上班
  • 打赏
  • 举报
回复
引用 17 楼 bandaoyu 的回复:
引用 16 楼 jiht594 的回复:
哦~~ 也就是说 语言层面是干不了这事的 最终还是要靠人的自觉和意识对吧


当然可以在语言层面解决,只是标准C++没有整数溢出检测,但是很多编译器都有扩展,有内置的溢出检测机制:
template <class T>
T add(const T lva, const T rva)
{
T a;
if (__builtin_add_overflow(lva, rva, &a))
throw std::runtime_error("Addition overflow");

return a;
}
bandaoyu 2019-04-28
  • 打赏
  • 举报
回复
没有办法防止溢出吗
bandaoyu 2019-04-20
  • 打赏
  • 举报
回复
引用 12 楼 weixin_44749415 的回复:
楼主自己看看,ini*int是什么类型?
楼上说了 还是int类型 如果溢出了 结果就不正确了,一般你们 int*int 用什么类型接?
lin5161678 2019-03-21
  • 打赏
  • 举报
回复
引用 5 楼 bdview 的回复:
[quote=引用 1 楼 sdghchj 的回复:]
溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊

引用 2 楼 zgl7903 的回复:
可以THROW抛出异常
你们真是误人子弟,有方法的:

在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
auto v = x*y;
std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)


链接:https://www.cnblogs.com/KunLunSu/p/7861330.html[/quote]你真是误人子弟 和 溢出处理 有关系?
weixin_44749415 2019-03-21
  • 打赏
  • 举报
回复
楼主自己看看,ini*int是什么类型?
bandaoyu 2019-03-21
  • 打赏
  • 举报
回复
引用 10 楼 Slzde_sub 的回复:
好,我看看。你给信息很重要
sdghchj 2019-03-19
  • 打赏
  • 举报
回复
如果你是要想知道int是否溢出,那用模板对于这个溢出问题反而没什么实际意义,直接定义普通函数就行了。 我的经验是C/C++本身并没有运行时溢出异常,不像C#有个checked关键字。

int mult(const int lva, const int rva)
 {
     long a = (long)lva * rva;
     if(a > std::numeric_limits<int>::max() || a < std::numeric_limits<int>::min() ){
           throw exception;
     }
     return (int)a;
 }
bdview 2019-03-19
  • 打赏
  • 举报
回复
引用 7 楼 sdghchj 的回复:
啊 这样啊,我还以为说 int*int 超过了int的范围会自动变为long 之类,没想到只是类型? 那么没有别的办法了吗
sdghchj 2019-03-19
  • 打赏
  • 举报
回复
引用 5 楼 bdview 的回复:
[quote=引用 1 楼 sdghchj 的回复:] 溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊
引用 2 楼 zgl7903 的回复:
可以THROW抛出异常
你们真是误人子弟,有方法的:
在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
    auto v = x*y;
    std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
    return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)

链接:https://www.cnblogs.com/KunLunSu/p/7861330.html[/quote]
引用 5 楼 bdview 的回复:
[quote=引用 1 楼 sdghchj 的回复:] 溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊
引用 2 楼 zgl7903 的回复:
可以THROW抛出异常
你们真是误人子弟,有方法的:
在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
    auto v = x*y;
    std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
    return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)

链接:https://www.cnblogs.com/KunLunSu/p/7861330.html[/quote]
引用 5 楼 bdview 的回复:
[quote=引用 1 楼 sdghchj 的回复:] 溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊
引用 2 楼 zgl7903 的回复:
可以THROW抛出异常
你们真是误人子弟,有方法的:
在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
    auto v = x*y;
    std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
    return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)

链接:https://www.cnblogs.com/KunLunSu/p/7861330.html[/quote] 你只是给了一种C++11新东西而已,那只是解决返回类型由计算结果类型来确定的问题,对于int * int,结果类型还是int,并不能解决溢出好么?
bdview 2019-03-19
  • 打赏
  • 举报
回复
引用 1 楼 sdghchj 的回复:
溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊

引用 2 楼 zgl7903 的回复:
可以THROW抛出异常
你们真是误人子弟,有方法的:

在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{
auto v = x*y;
std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?
模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{
return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)


链接:https://www.cnblogs.com/KunLunSu/p/7861330.html
bandaoyu 2019-03-18
  • 打赏
  • 举报
回复
引用 3 楼 Slzde_sub 的回复:
有没有默认异常处理呢,比如:

正常应该这样:

try
{
if(NULL == p)
{
throw 1011
}

……
}
catch()
……
但是要是我忘记了要对指针判断写成这样:

fun()
{

try{

……
free(p);

……
}
}

我这里忘记判断p是否为NULL而抛出异常,异常能不能捕捉到然后默认处理,不要让他崩溃?
zgl7903 2019-03-18
  • 打赏
  • 举报
回复
可以THROW抛出异常
sdghchj 2019-03-18
  • 打赏
  • 举报
回复
溢出跟模板函数有什么必然关系?普通一个语句a+b也可能溢出啊

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧