如何知道gcc/g++ 的默认C++版本

C++在C++ 11之后在保持向后兼容的情况下,语法增强了非常多,变化很大。得益于Move语义,和一些标准库的改进(如std::list的size()函数在C++11之前是O(n)的复杂度,从C++11开始变成常数复杂度)。一些旧C++代码即使什么改动也不做,只需要在新的C++标准下编译,也能获得性能提升。一般要给g++开启C++11需要用 -std=c++11,开启C++17则是 -std=c++17。那么,如果不添加这些选项,gcc/g++默认使用的C++版本号是什么呢? 如果你的gcc/g++版本号大于4.7的话,可以用如下命令获得默认c++版本。 kamus@shyyp.net:~$ g++ --version | head -1 g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 kamus@shyyp.net:~$ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus #define __cplusplus 201402L kamus@shyyp.net:~$ gcc -dM -E -x c++ /dev/null | grep -F __cplusplus #其实用gcc也可以 #define __cplusplus 201402L 如上所示,我的g++版本是9.3.0。它的默认C++版本是C++14。 这是我家用的电脑。我在公司的机器上运行结果如下: kamuszhou@centos ~ $ g++ --version | head -1 g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 kamuszhou@centos~ $ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus #define __cplusplus 199711L 如上所示,老版的g++ 4.8.4用的默认C++版本还是c++98 ...

November 21, 2021 · 1 min · kamus

用Range Adaptor,废弃replace_copy_if之类的函数

看看replace_copy_if的一个简单的例子: std::vector vec; boost::replace_copy_if(rng, std::back_inserter(vec), pred, new_value); 对于这种写法,如果使用Range Adaptor的话,则可以写成: std::vector vec; boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value)); 第二种写法有什么好处呢, 更高效率。因为std::back_inserter有额外的内存分配开销。 更灵活。因为第二种写法可以应用更多的适配器,比如: boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value) | boost::adaptors::reversed); 更安全。因为第二种写法没有用unbounded output iterator。

April 15, 2014 · 1 min · kamus

boost::io_service的poll_one和run_one有什么区别

boost::io_service的poll_one会立即返回(non-blocking),不管有没有已经被触发的处理函数(ready handler)。 而run_one有可能阻塞。如果还没有被触发的处理函数,run_one会阻塞到有一个handler被调用为止。 更多资料: http://think-async.com/ 呃。这篇日志也太短了!!! BOOST库真是个好东西啊~~好多写法很有现代脚本语言的taste。~~而且,那么丰富的库让生产效率大大提高了。 copyright ykyi.net

March 18, 2014 · 1 min · kamus

“右值引用”不是”右值”,而是”左值”

亮瞎你的狗眼了吧~这么拗口。 !来补一下C++基础吧~~ 右值引用 rvalue reference 右值 rvalue 左值 lvalue 什么是左值 lvalue呢。 本质上,左值是一个可以拿到其地址的表达式。左值lvalue里的l,本质上是locatable的缩写,因为lvalue通常可以放置于表达式的左边,于是就有了左left值的说法。 In C++, an lvalue is an expression whose address can be taken, essentially it’s a locator value. class MetaData { public: MetaData (int size, const std::string& name) : _name( name ) , _size( size ) {} // copy constructor MetaData (const MetaData& other) : _name( other._name ) , _size( other._size ) { cout << "copy\n"; } // move constructor MetaData (MetaData&& other) : _name( other._name ) , _size( other._size ) { cout << "move\n"; } std::string getName () const { return _name; } int getSize () const { return _size; } private: std::string _name; int _size; }; class ArrayWrapper { public: // default constructor produces a moderately sized array ArrayWrapper () : _p_vals( new int[ 64 ] ) , _metadata( 64, "ArrayWrapper" ) {} ArrayWrapper (int n) : _p_vals( new int[ n ] ) , _metadata( n, "ArrayWrapper" ) {} // move constructor ArrayWrapper (ArrayWrapper&& other) : _p_vals( other._p_vals ) , _metadata( move(other._metadata )) { other._p_vals = NULL; } // copy constructor ArrayWrapper (const ArrayWrapper& other) : _p_vals( new int[ other._metadata.getSize() ] ) , _metadata( other._metadata ) { for ( int i = 0; i < _metadata.getSize(); ++i ) { _p_vals[ i ] = other._p_vals[ i ]; } } ~ArrayWrapper () { delete [] _p_vals; } private: int *_p_vals; MetaData _metadata; }; ArrayWrapper get() { ArrayWrapper aw; return aw; } int main() { ArrayWrapper aw(get()); return 0; } 这段代码中的ArrayWrapper的移动构造函数能工作吗? ...

February 21, 2014 · 2 min · kamus

为什么指针可以做为迭代器使用呢

写了十几年代码了,今天才知道*为什么*指针可以做为迭代器使用。 这是因为: 首先,标准库里有这样一个template,它用来得到特定迭代器的相关特性: namespace std { template <class T> struct iterator_traits { typedef typename T::value_type value_type; typedef typename T::difference_type difference_type; typedef typename T::iterator_category iterator_category; typedef typename T::pointer pointer; typedef typename T::reference reference; }; } 而对于指针,又有这样一个模板特例化, namespace std { template <class T> struct iterator_traits<T*> { typedef T value_type; typedef ptrdiff_t difference_type; typedef random_access_iterator_tag iterator_category; typedef T* pointer; typedef T& reference; }; } 这个模板特例化的意思是:对于每一个指向类型T的指针,都被定义为一个可随机访问的迭代器。 更详细的,参见文章:介绍iterator_trait http://www.codeproject.com/Articles/36530/An-Introduction-to-Iterator-Traits copyright ykyi.net

February 14, 2014 · 1 min · kamus

C++准标准库boost转向github,并发布模块化boost(modular Boost)

难道是中文社区首次报道吗?我用中文搜索引擎没有搜索到modular boost的文章。 昨天想在STL的map容器上增加一个特性,即把std::map中所有的元素按照加入的先后时间用链表链接起来,以保存元素之间的时序关系。 为了这个基于std::map和std::list的新的容器能够兼容STL的算法,于是想实现stl compatible iterator。一口气读了几十页资料,发现最酷最好的方法是用boost的迭代器模板实现。纠结了很久,最终决定在我的工程中引入boost。为了获得快速开发的好处,还是加入更多的开源库吧。毕竟,如果自己造一个轮子,阅读者仍然要花时间理解你发明的轮子,还不如用已经广泛使用的轮子。况且,计划要引入boost中asio的proactor I/O模型。所以,今天就开始引入boost吧。 于是,发现boost早就发起了modular boost项目并把boost host在github.com上,如下地址: https://github.com/boostorg 在boost的官方网站上有模块化boost的FAQ: https://svn.boost.org/trac/boost/wiki/ModCvtFAQ 还有它的简单使用教程: https://svn.boost.org/trac/boost/wiki/TryModBoost#InstallingModularBoost 教程上说,如果把整个module boost git clone到本地,需要花费45分钟,如果下行网速是3Mbps,而且需要占用1.5G磁盘! 我晕~~ 另外FAQ上说:没办法只检出一个子库,暂时不能自动地解决依赖性问题。 原文: Is it possible to checkout only one library and its prerequisites? Not automatically. Automatic dependency resolution is planned for the future, but not as a part of the conversion to Git and Modular Boost. ...

February 13, 2014 · 1 min · kamus