std::abs()真的消失了吗?

mdc630 2008-02-11 03:16:30
今天在VC环境下验证一个解决名称冲突的小程序时,突然发现一个疑问:std::abs()消失了吗?

代码如下:
//====================================
#include<iostream>
using namespace std;

//-------------------------------------
int abs(int a){ return a>0 ? a : -a; }
//-------------------------------------
int main(){
int a = abs(-5);
int b = std::abs(-5);
std::cout<<a<<std::endl<<b<<std::endl;

return 0;
}
//====================================
运行之后居然弹出:
errors:'abs'is not a number of 'std'!!!
晕死!!!
难道std::abs()真的消失了吗???

试着变动一下:
//====================================
#include<iostream>
using namespace std;
//------------------------------------
namespace std {
/*#ifdef abs
#undef abs
#endif*/
template < class T >
inline const T & abs ( const T & a )
{
const T & retval = a < 0 ? -a : a;
return retval;
}
}
//-------------------------------------
int abs(int a){ return a>0 ? a : -a; }
//-------------------------------------
int main(){
int a = abs(-5);
int b = std::abs(-5);
std::cout<<a<<std::endl<<b<<std::endl;

return 0;
}
//====================================
顺利pass!难道是要显式调用命名空间或者类似重载一样的操作吗?
强大的STL怎么会把std::abs()弄丢了呢?
由此,我想到了std::min()和std::max(),居然也同样,做类似变动就OK了.

我把这个问题提出来,希望能起到一个抛砖引玉的作用,与大家共同探讨.
...全文
1106 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
min_2_max 2008-12-19
  • 打赏
  • 举报
回复
当然,前面加上:

#include <boost/utility/value_init.hpp>

这样用就可以了:

int i = mynamespace::abs(-1);
double d = mynamespace::abs(-1.0);

你甚至还可以对任何满足要求的类A“求绝对值”:

class A { /*...*/ };

A a, b;
// ...
a = mynamespace::abs(b);
min_2_max 2008-12-19
  • 打赏
  • 举报
回复
我也奇怪这个事情。

没有abs<>()这个模板函数很不爽,于是自己先做一个替者(放在另外的namespace里):

// my abs function
// it works not only for POD types, but also for
// user types that are default constructible and
// support operator<() and unary operator-()
template<class T> T abs(const T & x)
{
static boost::value_initialized<T> zero;
return (x < zero? -x : x);
}
AngelDevil 2008-02-18
  • 打赏
  • 举报
回复
mark
MagiSu 2008-02-18
  • 打赏
  • 举报
回复


一、写hello world的时候,include头文件stdio.h或者iostream,这个是必然的,原因我想大家都知道。
----------------------------------------------------
用一下cpp,处理一下代码,就知道了。


二、加上头文件会有编联代价?代价有多大?

这个问题要看程序的工程规模有多大,而一般的小程序(几万行代码左右)是体现不出来编联的代价的,当然这也不是绝对的,同时也要看CPU的负荷而定。总之,因为类似这个问题的简单求绝对值的小函数,两三行代码就可以搞定,还有内联函数可以解决多次调用的问题,如果再让CPU去连接程序外部头文件的话,肯定是得不偿失的。
-----------------------------------------------------
请你了解一下编译到底是怎么回事好么?
nscboy 2008-02-14
  • 打赏
  • 举报
回复
MSDN2005上讲std::abs在头文件<valarray>中.不知道这是不是STL的表中.
但是在VS2003(VC71)中楼主提供给的代码能够编译通过.
估计VC6无法编译通过跟VC6本身于标准的兼容性以及abs所在的头文件相关.
mdc630 2008-02-14
  • 打赏
  • 举报
回复
To iambic:

一、写hello world的时候,include头文件stdio.h或者iostream,这个是必然的,原因我想大家都知道。

二、加上头文件会有编联代价?代价有多大?

这个问题要看程序的工程规模有多大,而一般的小程序(几万行代码左右)是体现不出来编联的代价的,当然这也不是绝对的,同时也要看CPU的负荷而定。总之,因为类似这个问题的简单求绝对值的小函数,两三行代码就可以搞定,还有内联函数可以解决多次调用的问题,如果再让CPU去连接程序外部头文件的话,肯定是得不偿失的。
mdc630 2008-02-14
  • 打赏
  • 举报
回复
十分感谢各位的支持与关心,这两天在查阅相关资料,看来取证之路真的很漫长啊,要证明一个观点也不是一件容易的事情

啊,呵呵。

翻了几本关于STL的资料,并没有准确找到std::abs()的定义,但是,我想:我没有找到并不代表不存在这个函数,而且在没

有得到权威认证之前,我一直都会认为应该是存在这个函数的。

这两天的查阅,查到了一些内容,与大家一起分享并讨论。

mircosoft运行库定义了计算绝对值的int abs(int n);【http://learn.gxtc.edu.cn/NCourse/VC/yxk-a.htm】但不

能解决我们这个问题。

模板类valarray倒是定义了abs(),函数原型如下:

template<class T>
valarray<T> abs(const valarray<T>& X>);

包含了头文件<valarray>,做了相应的改动,运行之后仍然不行。

思来想去,还是觉得楼上几位朋友说得对,应该还是VC编译器的问题,我换了几个机器,几个版本的VC仍然存在同样的问题。

比如说个例子:

std::min()与std::max()肯定是在STL中的【STL在<algorithm>中定义了这两个模板函数】,但VC没有定义std::min

()与std::max(),原因是名字min与max和<windows.h>中传统的min/max宏定义有冲突。因而VC采用了另外的实现:

_cpp_min(),_cpp_max()。但是abs()却不见踪影,我想它应该不会消失,只是被处理成类似函数,但是我们没有找到而已。

众里寻它千百度,却不知它是否还在灯火阑珊处?
mimong_lin 2008-02-14
  • 打赏
  • 举报
回复
翻了几本关于STL的资料,并没有准确找到std::abs()的定义,但是,我想:我没有找到并不代表不存在这个函数,而且在没有得到权威认证之前,我一直都会认为应该是存在这个函数的。

abs不是C++才有的,是C++从C中继承过来的.本不关STL的事.
missilery 2008-02-13
  • 打赏
  • 举报
回复
可以参考一下
www.cppreference.com
iambic 2008-02-13
  • 打赏
  • 举报
回复
VC7.1其实挺不错了。就是有些bug,一般也碰不着。对系统的要求非常之低。有个免费的命令行版本,2005之后好像下不到了。

BCC55就不行了。整体速度还过得去,但是在高端技术的支持上落后的比较多。毕竟是2000年的产品了。不知道现在的Turbo Explorer系列怎么样。
longjurujiang 2008-02-12
  • 打赏
  • 举报
回复
受益了



iambic 2008-02-12
  • 打赏
  • 举报
回复
>再说了,楼上的几位一直强调加头文件,我个人一直认为为了这么一个小函数,就给程序加上一个头文件作为编译的联接代价,十分不划算.
>大家认为呢?

一、你写hello world的时候不include头文件stdio.h或者iostream?
二、加上头文件会有编联代价?代价有多大?

>在标准STL中已经包含了std::abs(),std::min(),std::max()

std::min肯定是在STL中的,abs倒底是不是STL的一部分,请查下你的编译/标准库手册。

>为什么强大的VC编怿器会...

强大不强大还要看你用的是什么版本的vc。


不管怎么说,在C++里面,要用一个函数必须包含正确的头文件。
  • 打赏
  • 举报
回复
请以
VC8或者更高的版本,gcc3.5或者更高,bcb5.5或者更高的编译器
的结果为依据,最好是3个编译器相同结果的时候再说这样的问题.
唐巧 2008-02-12
  • 打赏
  • 举报
回复
头文件应该是#include <cstdlib> ,这个确实比转鬼异,并不是大家想的cmath
jeff_nie 2008-02-11
  • 打赏
  • 举报
回复
嗯,学习了
arong1234 2008-02-11
  • 打赏
  • 举报
回复
PS: 在VC6.0 中,只有math.h中有它定义,不在std命名空间中
arong1234 2008-02-11
  • 打赏
  • 举报
回复
楼主7楼得帖子可能暗示一些问题:
1. abs实现了,但是不在cmath中
2. abs在你得那个编译器中根本没实现

但是无论如何,如果它实现了,include它所在得header文件是一个必要条件,这是最基本得原则
arong1234 2008-02-11
  • 打赏
  • 举报
回复
这不是代价得问题,无论STL实现与否,你不引用它得头文件,编译器不会自动帮你引入“实现了”得函数,对应得函数就必然找不到。

再说哪个函数不是通过头文件引入得?这是使用库得必然代价,你根本规避不了
也许不在上面得那些文件中,但是必然在哪个头文件中。既然找不到,你肯定没有包含对应得头文件

所以:既然你说STL实现了(哪个版本实现得?STL可没有标准版本,很可能这个版本实现,那个不实现)那么你就得首先弄明白它在哪个头文件实现得,如果找到那个头文件,只要#include对应头文件即可
mdc630 2008-02-11
  • 打赏
  • 举报
回复
再说了,楼上的几位一直强调加头文件,我个人一直认为为了这么一个小函数,就给程序加上一个头文件作为编译的联接代价,十分不划算.大家认为呢?
mdc630 2008-02-11
  • 打赏
  • 举报
回复
一直对abs()有<cmath>情节的大侠,你们在VC环境下一试便知嘛,多说无益.

#include <cstdlib>这条预编译指令并不能解决问题,参考了一下编译原理对unsigned int 的定义,好象问题并不是出在这里.

我设计的这个小程序主要目的是测试命名空间冲突的问题,在标准STL中已经包含了std::abs(),std::min(),std::max()等几个简单函数的定义模版,只是不明白的是:为什么强大的VC编怿器会把std::abs()给弄丢了呢???#include <cstdlib>这条预编译指令并不能解决问题,参考了一下编译原理对unsigned int 的定义,好象问题并不是出在这里.

这个问题也很容易解决,而且相信各位高手肯定还有更高效的代码,这个不是问题.问题是:知其然,怎么就不知其所以然呢???

郁闷中...
加载更多回复(6)
学习并掌握C++2.0(11+14+17+20)的新特性,学习线程及线程池的应用 ---------------------------------------------------给小白学员的3年学习路径及计划技术方面分三块:1.纯开发技术方向2.音视频流媒体专业方向3.项目实战---------------------------------------------------1.纯开发技术方向(1) C++必须要过硬(至少学会10本经典好书)(2) 系统级编程(Windows、Linux),必须特别熟练系统API,灵活运用(3) 框架与工具(Qt、MFC):必须精通其中一种。(4) 架构与设计模式:需要提升一个高度,不再是简单的编码,而是思维模式。(5) 驱动级别(如果有兴趣,可以深入到驱动级:包括Windows、Linux)(6) 最好学习点Java+Html+javascript等WEB技术。2.音视频流媒体专业方向(1) 音视频流媒体基础理论:   必须认真学会,否则看代码就是看天书(2) 编解码方向:精通h.264,h.265(hevc), 包括理论和各个开源库(ffmpeg,libx264,libx265,...)。(3) 直播方向:  精通各种直播协议(rtsp,rtmp,hls,http-flv,...), 钻研各个开源库(live555,darwin,srs,zlmediakit,crtmpserver,...)(4) 视频监控:  理论+开源库(onvif+281818)(EasyMonitor、iSpy、ZoneMinder(web)、...) 3.项目实战(1) Qt项目:  至少要亲手练习10个实战项目(网络服务器、多线程、数据库、图像处理、多人聊天、等等)(2)音视频项目:包括编解码、视频监控、直播等各个方向,都需要亲手实战项目,包括视频服务器、后台管理系统、前端播放器(多端)---------------------------------------------------  第1章 C++11新特性 41). nullptr关键字与新语法 42). auto和decltype类型推导 6 auto讲解 6 auto示例 7 decltype 83). for区间迭代 94). 初始化列表 105). 模板增强 11外部模板 11类型别名模板 12默认模板参数 126). 构造函数 13委托构造 13继承构造 147). Lambda 表达式 158). 新增容器 20std::array 20std::forward_list 21无序容器 22元组 std::tuple 239). 正则表达式 2610). 语言级线程支持 28多线程库简介 2811). 右值引用和move语义 31右值引用和move语义 32转移左值 3412). constexpr 35第2章 C++14新特性 36Lambda 函数 36类型推导 37返回值类型推导(Return type deduction) 37泛型lambda 39[[弃用的]]  [[deprecated]]属性 40二进制数字和数字分隔符 41第3章 C++17新特性 42安装GCC10.2 42安装msys2-x86_64-20200720 42更新镜像 42更新软件库 43安装 MinGW64 等必要的软件 43环境变量Path 43编译命令 43constexpr 44typename 45折叠表达式 47结构化绑定 48条件分支语句初始化 49聚合初始化 50嵌套命名空间 52lambda表达式捕获*this的值 53改写/继承构造函数 54用auto作为非类型模板参数 55__has_include 56fallthrough 57nodiscard 57maybe_unused 58第4章 C++20新特性 59编译命令 59concept 59typename 60explicit 61constinit 62位域变量的默认成员初始化 62指定初始化 63基于范围的for循环初始化 64放宽基于范围的for循环,新增自定义范围方法 65嵌套内联命名空间 66允许用圆括弧的值进行聚合初始化 67unicode字符串字面量 68允许转换成未知边界的数组 68likely和unlikely 69第5章 C++2.0(11/14/17/20)总结与分析 705.1 C语言与C++ 715.2 语言可用性的强化 725.2.1 常量 725.2.2 变量及其初始化 735.2.3 类型推导 745.2.4 控制流 765.2.5 模板 775.2.6 面向对象 815.3 语言运行期的强化 835.3.1 Lambda 表达式 835.3.2 右值引用 865.4 容器 885.4.1 线性容器 885.4.2 无序容器 895.4.3 元组 895.5 智能指针与内存管理 905.5.1 RAII 与引用计数 905.5.2 std::shared_ptr 905.5.3 std::unique_ptr 915.5.4 std::weak_ptr 91第6章 C++2.0多线程原理与实战 93什么是并发 93并发的方式 93为什么使用并发 95线程简介 96创建线程的三种方式 971. 通过函数 972.通过类对象创建线程 993.通过lambda表达式创建线程 101thread线程的使用 101互斥量与临界区 105期物Future 111条件变量 112原子操作 114内存模型 118第7章 C++2.0线程池原理与实战 120线程与线程池的基本原理 1201)、线程 1202)、线程的生命周期 1213)、什么是单线程和多线程 1214)、线程池 1225)、四种常见的线程池 123线程池的架构与流程 123线程池代码实战 125    

64,282

社区成员

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

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