模板函数怎么防止溢出?

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 的最大值怎么办? 你们是怎么防止溢出错误的
...全文
466 18 打赏 收藏 转发到动态 举报
写回复
用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也可能溢出啊
《程序设计方法》以Scheme语言为基础介绍计算和程序设计的一般理论和实践。《程序设计方法》由8个部分和7个独立的章节(第8、13、18、24、29、33、38章)组成。8个部分主要讨论程序设计,独立章节则介绍一些与程序设计和计算相关的话题。《程序设计方法》第1至第3部分介绍了基于数据驱动的程序设计基础。第4部分介绍了程序设计中的抽象问题。第5部分和第6部分是与递归及累积相关的内容。《程序设计方法》的最后两部分说明了设计程序的意义,阐述了如何应用前6个部分所描述的程序设计诀窍,以及使用赋值语句必须特别小心的一些问题。 《程序设计方法》可作为高等院校计算机科学与技术专业“程序设计导论”和“计算导论”的教材和教学参考书,也可作为函数式语言和Scheme语言的入门教材。 目录 · · · · · · 第一部分 简单数据的处理 第1章 学生、教师和计算机 3 第2章 数、表达式和简单程序 5 2.1 数和算术运算 5 2.2 变量和程序 6 2.3 字处理问题 9 2.4 错误 10 2.5 设计程序 12 第3章 程序就是函数加上变量定义 15 3.1 函数复合 15 3.2 变量定义 17 3.3 函数复合练习 18 第4章 条件表达式和函数 20 4.1 布尔类型和关系 20 4.2 函数和条件测试 22 4.3 条件和条件函数 25 4.4 条件函数的设计 27 第5章 符号信息 31 第6章 复合数据之一:结构体 34 6.1 结构体 34 6.2 补充练习:绘制简单图形 36 6.3 结构体定义 38 6.4 数据定义 41 6.5 设计处理复合数据的函数 43 6.6 补充练习:圆和长方形的移动 46 6.7 补充练习:刽子手游戏 49 第7章 数据的多样性 52 7.1 数据混合与区分 52 7.2 设计处理混合数据的函数 55 7.3 再论函数复合 58 7.4 补充练习:图形的移动 60 7.5 输入错误 61 第8章 语法和语义 63 8.1 Scheme的词汇 63 8.2 Scheme的文法 64 8.3 Scheme的含义 65 8.4 错误 68 8.5 布尔值表达式 70 8.6 变量定义 71 8.7 结构体的定义 72 第二部分 任意数目数据的处理 第9章 复合数据类型之二:表 77 9.1 表 77 9.2 任意长的表的数据定义 80 9.3 处理任意长的表 82 9.4 设计自引用数据定义的函数 84 9.5 更多关于简单表的例子 86 第10章 表的进一步处理 90 10.1 返回表的函数 90 10.2 包含结构体的表 93 10.3 补充练习:移动图片 98 第11章 自然数 100 11.1 定义自然数 100 11.2 处理任意大的自然数 101 11.3 补充练习:创建表,测试函数 103 11.4 自然数的另一种数据定义 104 11.5 更多与自然数有关的性质 108 第12章 三论函数复合 110 12.1 设计复杂的程序 110 12.2 递归的辅助函数 111 12.3 问题泛化与函数泛化 114 12.4 补充练习:字母的重新排列 117 第13章 用list构造表 119 第三部分 再论任意大数据的处理 第14章 再论自引用数据定义 125 14.1 结构体中的结构体 125 14.2 补充练习:二叉搜索树 131 14.3 表中的表 135 14.4 补充练习:Scheme求值 137 第15章 相互引用的数据定义 139 15.1 由结构体组成的表与结构体中的表 139 15.2 为相互引用的定义设计函数 144 15.3 补充练习:网页再谈 145 第16章 反复精化设计 147 16.1 数据分析 147 16.2 定义数据类型,再改进它们 148 16.3 改进函数和程序 150 第17章 处理两种复杂数据片段 152 17.1 同时处理两个表:第一种情况 152 17.2 同时处理两个表:第二种情况 154 17.3 同时处理两个表:第三种情况 156 17.4 函数的简化 159 17.5 设计读入两个复杂输入的函数 160 17.6 处理两个复杂输入的练习 161 17.7 补充练习:Scheme求值之二 164 17.8 相等与测试 165 第18章 局部定义和辖域 172 18.1 用local组织程序 172 18.2 辖域和块结构 183 第四部分 抽象设计 第19章 定义的相似性 189 19.1 函数的类似之处 189 19.2 数据定义的类似之处 195 第20章 函数也是值 199 20.1 语法和语义 199 20.2 抽象函数和多态函数的合约 200 第21章 抽象设计的例子 204 21.1 从实例中抽象 204 21.2 抽

64,643

社区成员

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

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