Tag: c ++ 11

noexcept,堆栈展开和性能

斯科特·迈耶斯(Scott Meyers)的新C ++ 11书以下草稿 (第2页第7-21行) 调用堆栈展开和可能展开的区别对代码生成有着惊人的巨大影响。 在一个noexcept函数中,如果一个exception传播出函数,优化器不需要保持运行时堆栈处于不可展开状态,也不必确保noexcept函数中的对象按照构造的相反顺序销毁, 。 结果是更多的优化机会,不仅在noexcept函数体内,而且在函数被调用的地方。 这种灵活性只适用于noexceptfunction。 带有“throw()”exception规范的函数缺less它,就像没有exception规范的函数一样。 相比之下, “C ++性能技术报告”第5.4节则描述了实现exception处理的“代码”和“表格”方式。 特别是,当没有任何exception抛出时,“table”方法显示没有时间开销,只有空间开销。 我的问题是这样的 – 斯科特·迈耶斯(Scott Meyers)谈论的是什么样的优化? 为什么这些优化不适用于throw() ? 他的意见只适用于2006 TR中提到的“代码”方法吗?

expression式模板和C ++ 11

让我们来看看expression式模板的一个特别的好处:可以使用ET来避免在重载操作符中出现的内存中的vector大小的临时对象,如: template<typename T> std::vector<T> operator+(const std::vector<T>& a, const std::vector<T>& b) { std::vector<T> tmp; // vector-sized temporary for_each(…); return tmp; } 在C ++ 11中,此函数的返回语句应用移动语义。 vector的副本。 这是一个胜利。 但是,如果我看一下像 d = a + b + c; 我看到上面的函数被调用了两次(对于operator+ ),而最后的赋值可以通过移动语义完成。 总共执行2个循环。 意思是我暂时放了一下,然后马上读回来。 对于大型vector而言,这会超出caching。 这比expression式模板更糟糕。 他们可以在一个循环中完成整个事情。 ET可以执行上面的代码相当于: for(int i=0 ; i < vec_length ; ++i) d[i] = a[i] + b[i] + […]

正确使用右值引用作为参数

以下面的方法为例: void Asset::Load( const std::string& Path ) { // complicated method…. } 这种方法的一般用法如下: Asset ExampleAsset; ExampleAsset.Load("image0.png"); 由于我们大多数时候都知道Path是一个临时右值,因此添加此方法的Rvalue版本是否有意义? 如果是这样,这是一个正确的实施; void Asset::Load( const std::string& Path ) { // complicated method…. } void Asset::Load( std::string&& Path ) { Load(Path); // call the above method } 这是一个正确的方法来编写右值版本的方法吗?

std ::线程 – 命名您的线程

新的C ++有这个std ::线程types。 奇迹般有效。 现在我想给每个线程一个更简单的debugging名称(如Java允许您)。 用pthreads我会做: pthread_setname_np(pthread_self(), "thread_name"); 但我怎样才能做到这一点与C ++ 0x? 我知道它在Linux系统下使用pthreads,但我想使我的应用程序可移植。 有没有可能?

C ++ 11 std ::函数比虚拟调用慢?

我正在创build一种机制,允许用户使用装饰器模式从基本构build块形成任意复杂的function。 这在function上是很好的,但是我不喜欢它涉及到大量的虚拟调用,特别是当嵌套深度变大的时候。 这让我很担心,因为复杂的function可能经常被调用(> 100.000次)。 为了避免这个问题,我试图把修饰器scheme一旦完成( to_function()就变成了std::function 。 所有的内部函数调用在std::function构造过程中都是连线的。 我认为这将比原来的装饰器scheme更快,因为在std::function版本中不需要执行虚拟查找。 唉,基准testingcertificate我错了:装饰器scheme实际上比我用它构build的std::function更快。 所以现在我想知道为什么。 也许我的testing设置是错误的,因为我只使用两个简单的基本function,这意味着可以caching的Vtable查找? 我使用的代码包含在下面,不幸的是它很长。 SSCCE // sscce.cpp #include <iostream> #include <vector> #include <memory> #include <functional> #include <random> /** * Base class for Pipeline scheme (implemented via decorators) */ class Pipeline { protected: std::unique_ptr<Pipeline> wrappee; Pipeline(std::unique_ptr<Pipeline> wrap) :wrappee(std::move(wrap)){} Pipeline():wrappee(nullptr){} public: typedef std::function<double(double)> FnSig; double operator()(double input) const{ […]

用于将默认参数值设置为默认构造函数的更好的语法

有人可能想用一个参数声明一个函数,并指定该参数的默认值是该types的默认构造函数的结果: void foo(a::really::long::type::name arg = a::really::long::type::name()); 有没有更好的语法,这不涉及inputtypes名称两次? 就像是: void foo(a::really::long::type::name arg = default); 我意识到我可以键入typedef的types名称,使其更漂亮,但我很好奇这样的语法是否存在。

什么是locking多个std :: mutex'es的最好方法?

当我们想要locking多个std::mutex ,我们使用std::lock() 。 但是std::lock()不提供RAIIfunction。 当我们想用RAII方式locking一个std::mutex时,我们使用std::lock_guard 。 但std::lock_guard无法安全地locking多个std::mutex 。 有没有办法利用这两种方法的优点,以RAII方式locking多个std::mutex ?

在C + + 11的原始string文字R“(…)”括号的基本原理是什么?

在C ++ 11中引入了一个非常方便的function,称为原始string文字,它是不含转义字符的string。 而不是写这个: regex mask("\\t[0-9]+\\.[0-9]+\\t\\\\SUB"); 你可以简单的写下这个: regex mask(R"(\t[0-9]+\.[0-9]+\t\\SUB)"); 更可读。 但是,注意在string周围必须放置额外的圆括号来定义原始string文字。 我的问题是,为什么我们甚至需要这些? 对我来说,这看起来相当丑陋,不合逻辑。 以下是我所看到的缺点: 额外的冗长,而整个function是用来使文字更紧凑 很难区分文字的正文和定义的符号 这就是我所说的难以区分的意思: "good old usual string literal" ^- body inside quotes -^ R"(new strange raw string literal)" ^- body inside parenthesis -^ 这里是亲: 更多的灵活性,在原始string中可用的字符更多,特别是当与分隔符一起使用时: "delim( can use () here )delim" 但是,嘿,如果你需要更多的灵活性,你有老好的可逃避的string文字。 为什么标准委员会决定用这些绝对不必要的括号来污染每一个原始string的内容? 那背后的理由是什么? 我没有提到的优点是什么?

std :: sort检查一个向量是否已经sorting?

我相信std::sort的C ++标准不能保证已经sorting的列表上的O(n)性能。 但是,我仍然想知道在执行sortingalgorithm之前,是否对STL(GCC,MSVC等)的任何实现进行std::is_sorted检查? 问另一种方式,什么样的性能可以期望(当然没有保证)在一个已sorting的容器上运行std::sort ? 注意:我在博客上发布了 C ++ 0x的GCC 4.5的一些基准testing 。 结果如下:

何时需要使用flag -stdlib = libstdc ++?

什么时候需要使用gcc编译时使用flag -stdlib=libstdc++作为编译器和链接器? 编译器是否自动使用libstdc ++? 我在Ubuntu 13.10上使用gcc4.8.2,我想使用c ++ 11标准。 我已经将-std=c++11传递给编译器。