Tag: c ++ 11

为什么仍然需要在使用语句的RHS中用typename来消歧一个依赖types?

我很清楚为什么需要为依赖types使用typename ,因为编译器可能无法在types和variables声明之间消除歧义,当它看到像T::type这样的东西时,请参阅这个答案,以获得很好的解释。 TL; DR :在像T::type * x;这样的expression式中T::type * x; ,编译器不能“知道” T::type是一个types,还是T一些特定的专门化中声明的variables。 然而,在类似的东西 using type = T::type; 没有什么暧昧的。 IMO, T::type 应该总是被parsing为一个types ,因为它是using语句的RHS的一部分。 但是,我们仍然需要在这里使用typename (至less根据gcc和clang) using type = typename T::type; 住在Coliru,gcc 住在Coliru,铛 Visual C ++ 似乎接受没有types名称的代码 ,但我没有太多的信心,编译器完全符合标准(事实上,它有许多非标准的扩展,例如绑定右值到非const引用)。 问题 :为什么这不是C ++ 11及更高版本中的typename规则的例外?

为什么这个嵌套可变参数模板是无效的参数?

如果我定义一个接受模板参数的struct模板Bar : template <template <int,bool,char> class> struct Bar {}; 我可以使用一个struct模板(如Zod来实例化它: template <int,bool,char> struct Zod {}; Bar<Zod> a; 我也可以使用嵌套的struct模板(如JKL来实例化它: struct GHI { template <int,bool,char> struct JKL {}; }; Bar <GHI::JKL> b; 为什么我不能使用嵌套可变参数struct模板(如DEF ?)实例化Bar : template <typename …Ts> struct ABC { template <Ts …> struct DEF {}; }; Bar<ABC<int,bool,char>::DEF> c; G ++ 4.9.2抱怨types/值不匹配; 而Clang 3.4.2的错误报告模板模板参数具有不同于其对应的模板参数的模板参数。

设置int的所有字节为(无符号字符)0,保证表示零?

这不是build议的做法 (也不是未定义的行为 )的问题,而是关于将整数types的所有字节转换为(unsigned char)0值的c ++标准实际保证的内容。 问题(S) 在下面的代码片段中, if语句使用的expression式保证在c ++ 11中被评估为true ? std::memset ( reinterpret_cast<char*> (&a), // int a; (unsigned char)0, sizeof (int) ); if (a == 0) { … } 通过阅读C99和C ++ 11标准(本文后面的部分)的引用,我们发现C99明确保证所有位设置为0的整数types将表示该types中的值0 。 我无法在C ++ 11标准中find这个保证。 有没有这样的保证? 前面的代码片段的结果是否是特定于实现的? 在C99(ISO / IEC 9899:1999) 5.2.1.2/1多字节字符 所有位为零的字节应被解释为与移位状态无关的空字符。 这样的字节不应该作为任何其他多字节字符的一部分出现。 6.2.6.2/1整数types 任何填充位的值都是未指定的。 45)符号位为零的有符号整数types的有效(无陷阱)对象表示是相应的无符号types的有效对象表示,并且表示相同的值。 对于任何整数types,所有位都为零的对象表示应该是该types中零值的表示。 在C ++ 11(ISO / IEC […]

set和unordered_set在C ++中有什么区别?

遇到这个很好的问题,这是相似的,但由于它具有不同的哈希表的实现,因为它具有同步的访问器/ mutators HashMap和Hashtable之间的差异,因为它谈论Java是相似的但是完全不一样? 那么set和unordered_set的C ++实现有什么区别呢? 这个问题可以扩展到map vs unordered_map等其他C ++容器。 这是我的初步评估 set :虽然标准并没有明确地要求它被实现为树,但是时间复杂性约束被要求为find / insert操作,意味着它总是被实现为树。 通常作为高度平衡的RB树(如在GCC 4.8中所见)。 由于它们是高度平衡的,它们对于find()具有可预测的时间复杂度, 优点:紧凑(与其他DS相比) Con:访问时间复杂度是O(lg n) unordered_set :虽然标准没有明确地要求它被实现为树,但是时间复杂性约束要求它的查找/插入操作,意味着它总是被实现为散列表。 优点: 更快(承诺O(1)分期付款) 与树DS相比,易于将基本原语转换为线程安全的 缺点: 查找不保证是O(1)最坏的情况是O(n) 不像树那么紧凑。 (为了实际的目的,加载因子从不是1) 注意:散列表的O(1)来自于没有碰撞的假设。 即使使用0.5的载荷系数,每第二次可变插入也会导致碰撞。 可以观察到,哈希表的负载因子与访问其中的元素所需的操作的数量成反比。 更多的我们减less#operations,更稀疏的哈希表。 当存储的元素的大小与指针相当时,开销是非常重要的。 编辑:由于大多数人说的问题包含了足够的答案,所以我将这个问题改为“我错过了地图/设置性能分析之间的任何区别,应该知道的区别?

将shared_ptr <Derived>作为shared_ptr <Base>传递

将派生types的shared_ptr传递给带有基types的shared_ptr的函数,最好的方法是什么? 我通常通过引用传递shared_ptr以避免不必要的副本: int foo(const shared_ptr<bar>& ptr); 但如果我尝试做类似的事情,这是行不通的 int foo(const shared_ptr<Base>& ptr); … shared_ptr<Derived> bar = make_shared<Derived>(); foo(bar); 我可以使用 foo(dynamic_pointer_cast<Base, Derived>(bar)); 但这似乎是次优的有两个原因: dynamic_cast对于简单的派生到基础的演员似乎有点过分。 据我所知, dynamic_pointer_cast创build一个副本(尽pipe是临时的)传递给函数的指针。 有更好的解决scheme吗? 后人更新: 原来是一个缺less头文件的问题。 另外,我在这里试图做的是被认为是反模式。 通常, 不影响对象的生命周期(即对象在函数期间保持有效的函数)的函数应该使用一个普通的引用或指针,例如int foo(bar& b) 。 使用一个对象的函数(即给定对象的最终用户)应该通过值来获取unique_ptr ,例如int foo(unique_ptr<bar> b) 。 调用者应该std::move值移入该函数。 延长对象生命周期的函数应该通过值来获取shared_ptr ,例如int foo(shared_ptr<bar> b) 。 避免循环引用的通常build议适用。 详情请参阅Herb Sutter的“ 回归基础” 。

C ++ 11中有没有并发容器?

特别是,我正在寻找一个阻塞队列。 C ++ 11中有这样的事情吗? 如果不是,我的其他select是什么? 我真的不想自己去了线程水平了。 太容易出错。

从unique_ptr创build一个shared_ptr

在我最近回顾的一段代码中,用g++-4.6编译得很好,我遇到了一个奇怪的尝试,从std::unique_ptr创build一个std::shared_ptr : std::unique_ptr<Foo> foo… std::make_shared<Foo>(std::move(foo)); 这对我来说似乎很奇怪。 这应该是std::shared_ptr<Foo>(std::move(foo)); afaik,虽然我不完全熟悉的动作(我知道std::move只是一个演员,没有得到移动)。 使用此SSC上的不同编译器进行检查(NUC *)E #include <memory> int main() { std::unique_ptr<int> foo(new int); std::make_shared<int>(std::move(foo)); } 汇编结果: g ++ – 4.4.7给出编译错误 g ++ – 4.6.4编译没有任何错误 g ++ – 4.7.3给出了内部编译器错误 g ++ – 4.8.1给出了编译错误 铿锵声++ – 3.2.1编译没有任何错误 所以问题是:哪个编译器在标准方面是正确的? 标准是否要求这是一个无效的陈述,一个有效的陈述,或者这只是未定义的? 加成 我们已经同意,其中一些编译器(如clang ++和g ++ – 4.6.4)允许转换,而不应该转换。 然而,使用g ++ – 4.7.3(它在std::make_shared<Foo>(std::move(foo)); )上产生内部编译器错误,正确地拒绝了int bar(std::move(foo)); 由于这种巨大的行为差异,我将这个问题保持原样,尽pipe其中的一部分可以通过减lessint […]

Lambdaexpression式作为类模板参数

可以使用lambdaexpression式作为类模板参数吗? (请注意,这是一个非常不同的问题,它会询问一个lambdaexpression式本身是否可以模板化。) 我问你是否可以做这样的事情: template <class Functor> struct Foo { }; // … Foo<decltype([]()->void { })> foo; 这在例如一个类模板具有不同的参数(如equal_to或者其他的东西)的情况下是有用的,这些参数通常被实现为equal_to函子。 例如,假设我想实例化一个使用我自己的自定义相等比较函数的哈希表。 我希望能够这样说: typedef std::unordered_map< std::string, std::string, std::hash<std::string>, decltype([](const std::string& s1, const std::string& s2)->bool { /* Custom implementation of equal_to */ }) > map_type; 但是我在GCC 4.4和4.6上testing了这个,并且不起作用,显然是因为由lambdaexpression式创build的匿名types没有默认的构造函数。 (我记得与boost::bind类似的问题。)是否有一些原因,标准草案不允许这样做,或者我错了,它是允许的,但GCC只是落后于他们的实施?

从unordered_map获取键和值的列表

从unordered_map获取键和值的列表(作为vector )的最有效方法是什么? 为了具体,假设有问题的地图是一个unordered_map<string, double> 。 然后,我想将键作为一个vector<string> ,并将这些值作为一个vector<double> 。 unordered_map<string, double> um; vector<string> vs = um.enum_keys(); vector<double> vd = um.enum_values(); 我可以遍历地图并收集结果,但有没有更有效的方法? 有一个方法也可以用于普通地图,因为我可能会切换到这个地方。

什么是std :: labs()那里?

浏览cppreference时,我读了std::abs()函数。 在那个页面上,我也看到了一个std::labs()函数。 它具有与std::abs()重载( long )之一相同的原型。 long abs( long n ); long labs( long n ); 和 long long abs( long long n ); long long llabs( long long n ); 所以, 究竟是什么std::labs()呢? 何时何地使用std::labs() ? std::abs()和std::labs()之间有什么区别?