Questions tagged «c++11»

C ++ 11是2011年批准的C ++标准的名称。它取代了以前的C ++ 03标准,添加了各种核心语言更改和修补程序以及改进和扩展的标准库。

2
标记C ++函数constexpr是否曾经很糟糕?
鉴于功能非常微不足道, int transform(int val) { return (val + 7) / 8; } 很明显,将这个函数变成一个constexpr函数很容易,允许我在定义constexpr变量时使用它,如下所示: constexpr int transform(int val) { return (val + 7) / 8; } 我的假设是,这严格来说是一种改进,因为该函数仍可以在非constexpr上下文中调用,并且现在也可以用于帮助定义编译时常量变量。 我的问题是,在某些情况下这是个坏主意吗?就像通过执行此功能一样,constexpr我是否可以遇到在特定情况下该功能将不再可用或行为异常的情况?
26 c++  c++11 

1
C ++ 11中auto关键字的动机和陷阱(?)
我最近想知道为什么auto在C ++ 11中选择了关键字来标记必须由编译器推断类型的变量,例如 auto x = 1; 以来 var 在其他编程语言(例如C#,Scala,JavaScript)中似乎更常见,并且 据我所知,autobreaks向后兼容的新语义(它很少使用,但在以前的C ++版本中具有不同的含义,请参见例如此处)。 我想问一下是否有一个特殊的原因选择auto(赞成var或其他任何关键字)。在C ++ 11标准发布之前是否有关于此问题的特定讨论? 另外,在使用C ++ 11编译器重新编译旧版C ++代码时,是否应该注意任何可能的不兼容性?

6
我是否应该使用新的C ++ 11“自动”功能,尤其是在循环中?
使用auto关键字的利弊是什么,尤其是在for循环中? for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ ) { it->something(); } for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ ) { it->second->something(); } for(auto it = x.begin(); it != x.end(); it++ ) { it->?? } 似乎,如果您不知道是否有地图或矢量的迭代器,就不会使用first还是second直接访问对象的属性,是吗? 这让我想起了C#关于是否使用关键字的争论var。到目前为止,我得到的印象是,在C ++世界中,人们auto比var在C#世界中更愿意采用关键词。对我来说,我的第一个直觉是我想知道变量的类型,以便知道可以对它执行哪些操作。
20 c++  c++11 

5
将参数作为const传递时是否过早优化?
“过早的优化是万恶之源” 我认为我们都可以同意。我尽力避免这样做。 但是最近我一直想知道通过const Reference而不是Value传递参数的做法。我已经被教导/了解到,非平凡的函数参数(即大多数非原始类型)最好通过const引用传递-我读过的很多书都将其推荐为“最佳实践”。 我仍然不禁感到奇怪:现代的编译器和新的语言功能可以解决奇迹,因此我所学的知识可能已经过时了,而且如果两者之间存在任何性能差异,我实际上也不会费心去剖析。 void fooByValue(SomeDataStruct data); 和 void fooByReference(const SomeDataStruct& data); 我所学的做法是-传递const引用(对于非平凡类型默认为)-过早优化吗?

2
对现代C ++范例的最佳概述?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 我曾经在8到10年前广泛地编写C ++。从那以后,出于专业原因,我开始使用C#。但是,我有时会看到类似 “如果您仍在手动跟踪指针引用,那么您做错了” 要么 “只要您使用的是RAII之类的现代概念,并且不像正在恢复的C开发人员那样手动分配内存,C ++绝对是安全的。” 两者都是十年前的标准程序。我已经看到,最近C ++有了很大的改进。特别是C ++ 0x似乎具有一些新功能。对于“ C / old C ++”程序员来说,赶上“现代” C ++模式和实践的最佳资源是什么?

2
与std :: bitset相比,c风格的位操作有什么优势吗?
我几乎只在C ++ 11/14中工作,通常在看到这样的代码时会畏缩: std::int64_t mArray; mArray |= someMask << 1; 这只是一个例子。我说的是一般的按位操作。在C ++中,真的有什么意义吗?上面的内容容易引起误解且容易出错,而使用std::bitset可以使您: std::bitset通过调整模板参数并让实现负责其余工作,可以更轻松地根据需要修改的大小,以及 花更少的时间弄清楚正在发生的事情(并可能犯错误),并std::bitset以类似于std::array或其他数据容器的方式编写。 我的问题是;除了向后兼容以外,还有什么理由不使用std::bitset原始类型吗?

2
出于对临时性的引用,该归咎于谁?
乍一看,以下代码看起来无害。用户使用该功能bar()与某些库功能进行交互。(自从bar()返回对非临时值或类似值的引用以来,这甚至可能已经工作了很长时间。)但是现在,它只是返回的新实例B。B再次具有一个函数a(),该函数返回对可迭代类型的对象的引用A。用户希望查询该对象,这会导致段错误,因为迭代开始之前销毁了B返回的临时对象bar()。 我不确定是谁(图书馆或用户)对此负责。所有库提供的类对我来说看起来都很干净,并且肯定没有做任何其他事情(返回对成员的引用,返回堆栈实例等)。用户似乎也没有做错任何事情,他只是在迭代某个对象而没有做任何与该对象寿命有关的事情。 (一个相关的问题可能是:应该建立一个通用规则,即代码不应对循环头中多个链接调用所检索的内容进行“基于范围的迭代”,因为这些调用中的任何一个都可能返回a右值?) #include <algorithm> #include <iostream> // "Library code" struct A { A(): v{0,1,2} { std::cout << "A()" << std::endl; } ~A() { std::cout << "~A()" << std::endl; } int * begin() { return &v[0]; } int * end() { return &v[3]; } int v[3]; }; struct B { …
15 c++11 

6
使用朋友类在C ++中进行单元测试私有方法
我知道这是一个有争议的做法,但是让我们假设这对我来说是最佳选择。我想知道执行此操作的实际技术是什么。我看到的方法是这样的: 1)与我要测试的方法的班级做一个朋友班。 2)在friend类中,创建一个公共方法,该公共方法调用被测试类的私有方法。 3)测试好友类的公共方法。 这是一个简单的示例来说明上述步骤: #include <iostream> class MyClass { friend class MyFriend; // Step 1 private: int plus_two(int a) { return a + 2; } }; class MyFriend { public: MyFriend(MyClass *mc_ptr_1) { MyClass *mc_ptr = mc_ptr_1; } int plus_two(int a) // Step 2 { return mc_ptr->plus_two(a); } private: …

1
通用C ++包装器能否实现Rust的所有权模型?
浏览有关Rust的并发安全性的这篇文章: http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html 我想知道在C ++ 11(或更新版本)中可以实现多少这些想法。特别是,我可以创建一个所有者类,将所有权转移到可能传递给它的任何方法吗?似乎C ++有太多传递变量的方法,这是不可能的,但是也许我可以对类或模板施加一些限制,以确保每次方法传递都执行某些模板代码?

2
这是一个好模式吗:用一系列lambda代替长函数?
我最近遇到以下情况。 class A{ public: void calculate(T inputs); } 首先,A表示物理世界中的一个对象,这是不将类拆分的有力论据。现在,calculate()事实证明它是一个相当长且复杂的功能。我认为它有三种可能的结构: 写成一堵墙-优势-所有信息都集中在一个地方 private在类中编写实用程序函数,并在calculate主体中使用它们-缺点-类的其余部分不了解/不在意/不了解这些方法 编写calculate以下方式: void A::calculate(T inputs){ auto lambda1 = () [] {}; auto lambda2 = () [] {}; auto lambda3 = () [] {}; lambda1(inputs.first_logical_chunk); lambda2(inputs.second_logical_chunk); lambda3(inputs.third_logical_chunk); } 可以认为这是好事还是坏事?这种方法有什么问题吗?总而言之,当我再次面临同样的情况时,我是否应该将此视为一种好方法? 编辑: class A{ ... public: // Reconfiguration of the algorithm. void set_colour(double …
14 c++11  lambda 

1
对象生存期不变性与移动语义
很久以前,当我学习C ++时,我就强烈强调C ++的部分意思是就像循环具有“循环不变式”一样,类也具有与对象生命周期相关的不变式-应该是正确的只要物体还活着 应该由构造函数建立并由方法保留的事物。封装/访问控制可帮助您强制执行不变式。RAII是您可以使用此想法做的一件事。 从C ++ 11开始,我们现在有了移动语义。对于支持移动的类,从某个对象移动不会正式终止其生命周期,因为该移动应该使它处于某种“有效”状态。 在设计一个类时,如果将其设计为仅保留该类的不变性直到将其移出之前,是不好的做法吗?或者是说没关系,如果它可以让你让它走得更快。 具体来说,假设我有一个不可复制但可移动的资源类型,如下所示: class opaque { opaque(const opaque &) = delete; public: opaque(opaque &&); ... void mysterious(); void mysterious(int); void mysterious(std::vector<std::string>); }; 无论出于何种原因,我都需要为此对象创建一个可复制的包装,以便可以在某些现有的调度系统中使用它。 class copyable_opaque { std::shared_ptr<opaque> o_; copyable_opaque() = delete; public: explicit copyable_opaque(opaque _o) : o_(std::make_shared<opaque>(std::move(_o))) {} void operator()() { o_->mysterious(); } void …

1
C ++ 11支持高阶列表功能
大多数函数式编程语言(如Common Lisp的,计划/球拍,Clojure中,Haskell中,斯卡拉,ocaml的,SML)支持列出了一些常见的高阶功能,如map,filter,takeWhile,dropWhile,foldl,foldr(见如Common Lisp的,计划/球拍, Clojure并排参考表,Haskell,Scala,OCaml和SML文档。) C ++ 11是否在列表上具有等效的标准方法或函数?例如,考虑以下Haskell代码段: let xs = [1, 2, 3, 4, 5] let ys = map (\x -> x * x) xs 如何在现代标准C ++中表达第二个表达式? std::list<int> xs = ... // Initialize the list in some way. std::list<int> ys = ??? // How to translate the Haskell expression? 上面提到的其他高阶函数呢? …

2
如何处理C ++ 11中auto_ptr弃用的设计更改?
我们正在测试C ++ 11(即-std=c++11)下的库。该库使用auto_ptr以下模式: Foo* GetFoo() { autoptr<Foo> ptr(new Foo); // Initialize Foo ptr->Initialize(...); // Now configure remaining attributes ptr->SomeSetting(...); return ptr.release(); } C ++ 11已弃用auto_ptr,因此我们希望远离它。 但是,该代码同时支持C ++ 03和C ++ 11,因此它不是yanking那样简单auto_ptr。还值得一提的是该库没有外部依赖项。它使用C ++ 03; 并且不使用Autotools,Cmake,Boost等 auto_ptr在保持与C ++ 03的兼容性的同时,我们应如何处理设计更改以脱离C ++ 11?
12 design  c++  c++11 

3
实现与C ++ 11的前向兼容性
我在大型软件应用程序上工作,该应用程序必须在多个平台上运行。其中一些平台支持C ++ 11的某些功能(例如MSVS 2010),而某些则不支持任何功能(例如GCC 4.3.x)。我希望这种情况会持续数年(我的最佳猜测:3-5年)。 鉴于此,我想设置一个兼容性接口,以便(尽可能)人们可以编写C ++ 11代码,而这些代码仍可以用较旧的编译器进行编译,而只需很少的维护。总体而言,目标是尽可能合理地最小化#ifdef,同时仍在支持它们的平台上启用基本的C ++ 11语法/功能,并在不支持它们的平台上提供仿真。 让我们从std :: move()开始。实现兼容性的最明显方法是将这样的内容放入公共头文件中: #if !defined(HAS_STD_MOVE) namespace std { // C++11 emulation template <typename T> inline T& move(T& v) { return v; } template <typename T> inline const T& move(const T& v) { return v; } } #endif // !defined(HAS_STD_MOVE) 人们可以这样写 …
12 c++  c++11 

2
可以在较旧的C ++编译器中链接已编译的C ++ 11库(lib,dll等)吗?
旧的C ++编译器(例如VS2008和gcc3.4)可以与用C ++ 11编写的外部库链接吗? 我的想法是,C ++ 11 .lib文件在此阶段仅是字节代码,并且只要它可以解析和可调用,就不应打扰旧的编译器如何生成它。 我正在开发一个小型库,其API仍应支持C ++ 03用户。因此,展望未来,我想知道是否可以使用诸如此类的有用功能来实现我的库std::unique_ptr,还是我必须坚持使用boost::?
12 c++  c++11 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.