小编Ori*_*ent的帖子

initializer_list不可变性导致过度复制

为什么访问权限std::initializer_list不允许我们更改其内容?std::initializer_list当它用于其主要目的(初始化容器)时,这是一个很大的缺点,因为它的使用会导致过多的复制构造/复制分配,而不是移动构造/移动分配.

#include <initializer_list>
#include <iostream>
#include <vector>

#include <cstdlib>

struct A
{

    A() = default;
    A(A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A(A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
    A & operator = (A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
    A & operator = (A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }

};

int
main()
{
    std::vector< A >{A{}, A{}, A{}};
    return EXIT_SUCCESS; …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list move-semantics c++11 c++14

11
推荐指数
1
解决办法
318
查看次数

转发成员函数的cv-ref-qualifier

如果没有另一个超载(比如,f(T &)f(volatile T &&)一个(部件)函数模板的)template< typename T > f(T &&);,然后T &&是所谓的转发参考,并且T要么是U,或U &对于一些CV-合格类型U.但是对于成员函数的cv-ref-qualifiers,没有这样的规则.在struct S { void f() && { ; } };一个S::f()总是rvalue-reference限定符.

在通用代码中volatile,如果所有这些函数通常都做同样的事情,那么避免定义4(甚至8,如果我们也考虑限定符)某些成员函数的重载将是非常有用的.

中出现的这种方式的另一个问题,这是不可能的,以限定一个有效的CV-REF-限定符*this在特定的意义.以下代码不允许确定成员函数的ref限定符operator ()是否&&&.

#include <type_traits>
#include <utility>
#include <iostream>

#include <cstdlib>

#define P \
{                                                                       \
    using this_ref = decltype((*this));                                 \ …
Run Code Online (Sandbox Code Playgroud)

c++ member-functions c++11 ref-qualifier c++17

11
推荐指数
1
解决办法
415
查看次数

将命名空间实验注入std

将名称空间std::experimental注入std如下所示是不好或好的parctice ?

namespace std
{
namespace experimental
{
}
using namespace experimental;    
}

#include <experimental/optional>

int main()
{
    std::optional< int > o;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

甚至以更现代的形式:

#if __has_include(<optional>)
# include <optional>
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
namespace std
{
using namespace experimental;    
}
#else
#error !
#endif

int main()
{
    std::optional< int > o;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

引入std::experimental"子命名空间" 的意图很明确,因为std::experimental目前包含大量.我认为它们很可能会在namespace std没有任何实质性更改的情况下迁移到目前用户代码可以依赖于此(我完全错了吗?).否则,所有这些代码都应该重构,std::experimental::以便std::将来改变.这不是什么大不了的事,但可能有理由不这样做.

问题是关于生产代码和不太严肃的代码.

c++ stl c++11 c++14

11
推荐指数
2
解决办法
1773
查看次数

适用于所有x64平台的gcc通用游行

GCC有-march=-mtune选项,描述在这里.但是,选择x64平台作为通用选项的选项并不明显.我说,-mtune=generic值,但-march=对于64位都没有.

我怀疑-march=nocona(随处可见)甚至-march=i686 -m64是解决方案,但我不确定.

64-bit gcc

10
推荐指数
1
解决办法
1万
查看次数

在Qt Creator中使用libc ++而不是libstdc ++

我在Ubuntu 14.04.1上安装了clang ++ 3.5,g ++ 4.9.1,libc ++Qt Creator.

我通常使用clang ++作为编译器.但最近我发现的libstdc ++G ++作为C++标准库.据我所知,后者目前尚未完全支持C++ 14的创新.

clang ++编译项目时如何用libc ++替换libstd ++

我已经做了什么(.pro-file):

QMAKE_CXXFLAGS_CXX11 = -std=gnu++1y
CONFIG *= c++11
QMAKE_CXXFLAGS += -stdlib=libc++
LIBS += -stdlib=libc++
Run Code Online (Sandbox Code Playgroud)

但是Qt Creator编辑器仍然使用libstdc ++DEPENDPATH浏览包含的文件.如何解决这种不良行为?也许我应该在mkspec文件中修复一些东西?

c++ qt clang libc++ c++14

10
推荐指数
1
解决办法
3196
查看次数

特性检查模板类的某些特化是否是特定类的基类

std::is_base_of现代STL.它允许我们确定第二个参数是从第一个参数派生还是它们是相同的类,或者确定它们之间是否存在这样的关系.

是否有可能确定一个类是否来自某个具体的模板类,而不区分其专业化所涉及的具体实际参数?

说,我们有;

template< typename ...types >
struct B {};
Run Code Online (Sandbox Code Playgroud)

template< typename ...types >
struct D : B< types... > {};
Run Code Online (Sandbox Code Playgroud)

是否可以定义类型特征:

template< typename T > is_derived_from_B;
Run Code Online (Sandbox Code Playgroud)

这样的派生自std::true_type何时T的任何特化D和派生自std::false_typeif T不是从任何专业化派生而来的B

c++ traits type-traits c++11 c++14

10
推荐指数
1
解决办法
1611
查看次数

通过引用将函数对象传递给std算法

通过转发引用而不是通过值将函数对象传递给STL算法不是更好吗?它将允许一个人利用operator ()传递的函数对象的ref限定符.

有几个约问题std::for_each算法SO(1,2),这是考虑与传递给函数对象的可观察到的状态的改变的问题std::for_each.

通过左值传递传递函数对象会将问题解决为副作用,即使对于那些不能返回功能对象的算法(因为它们应该返回,比如输出迭代器或其他值).

例如,std::for_each可以从(从libc ++复制)更改算法:

template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
  for (; __first != __last; ++__first)
    __f(*__first);
  return _GLIBCXX_MOVE(__f);
}
Run Code Online (Sandbox Code Playgroud)

至:

template<typename _InputIterator, typename _Function>
_Function &&
for_each(_InputIterator __first, _InputIterator __last, _Function && __f)
{
  for (; __first != __last; ++__first)
    _GLIBCXX_FORWARD(_Function, __f)(*__first);
  return _GLIBCXX_FORWARD(_Function, __f);
}
Run Code Online (Sandbox Code Playgroud)

或者(如果允许这种改变)std::for_each可以返回void而不会丧失功能.std::forward对于所有其他算法<numeric><algorithm>算法,类似的更改(从传递值到传递转发引用并将所有调用更改为调用ed函数对象而不仅仅是非const-lvalue)都是可能的.

我知道一个部分的解决方法:是传递对象,包裹std::ref …

c++ algorithm stl c++11 c++14

10
推荐指数
1
解决办法
718
查看次数

shared_ptr的静态成员函数make_shared

使用libc ++std::shared_ptr::make_shared()在公共部分找到静态成员函数.当我已经为特化定义了类型别名时,它非常方便std::shared_ptr:

using T = int;
using P = std::shared_ptr< T >;
auto p = P::make_shared(123); // <=> std::make_shared< T >(123)
static_assert(std::is_same< decltype(p), P >::value);
Run Code Online (Sandbox Code Playgroud)

我担心符合标准,因为物品(1,2)从可信赖的来源没有提及静态成员函数make_sharedstd::shared_ptr.

目前使用该功能是不是很糟糕?为什么?

c++ stl shared-ptr c++11 c++14

10
推荐指数
1
解决办法
703
查看次数

使用公共迭代器访问数组数组的元素

是否在C++中使用未定义的行为来访问相邻数组中的元素,如下面的代码所示?

#include <type_traits>
#include <algorithm>
#include <iterator>

int main()
{
    int a[10][10];
    static_assert(std::is_standard_layout< decltype(a) >::value, "!");
    std::fill(std::begin(*std::begin(a)), std::end(*std::prev(std::end(a))), 0);
    struct B { int b[10]; };
    B b[10];
    static_assert(std::is_standard_layout< decltype(b) >::value, "!");
    std::fill(std::begin(std::begin(b)->b), std::end(std::prev(std::end(b))->b), 0);
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,我认为对于POD类型来说,以任何方式访问底层内存是合法的,但是那些std::*东西呢?

如果我改变一切什么begin/endrbegin/rend

c++ arrays stl language-lawyer

10
推荐指数
1
解决办法
240
查看次数

有条件的琐碎的析构函数

发明一个有区别的联合/标记变体我得出结论,在编译时"在一些条件下使析构函数变得微不足道"这样的特性需要特别需要.我的意思是某种SFINAE或类似的东西(伪代码):

template< typename ...types >
struct X
{
    ~X() = default((std::is_trivially_destructible< types >{} && ...))
    {
        // non-trivial code here
    }
};
Run Code Online (Sandbox Code Playgroud)

这意味着如果条件default(*)true,则析构函数的定义等于~X() = default;,但如果是false{ // ... }使用body来代替.

#pragma once
#include <type_traits>
#include <utility>
#include <experimental/optional>

#include <cassert>

template< typename ...types >
class U;

template<>
class U<>
{

    U() = delete;

    U(U &) = delete;
    U(U const &) = delete;
    U(U &&) = delete;
    U(U const …
Run Code Online (Sandbox Code Playgroud)

c++ destructor variant c++11 c++14

9
推荐指数
1
解决办法
1341
查看次数