小编Tob*_*ull的帖子

允许在单个完整表达式中移动两次

假设一个具有以下原型的功能

template<typename T>    
std::unique_ptr<T> process_object(std::unique_ptr<T> ptr);
Run Code Online (Sandbox Code Playgroud)

该函数可以返回传递给它的对象(移动版本)或完全不同的对象.

使用此函数是合法的C++如下吗?

std::unique_ptr<Widget> pw(new Widget());

pw = process_object(std::move(pw));
Run Code Online (Sandbox Code Playgroud)

如果我没记错的话,有一个C/C++规则禁止在一个完整的表达式中多次修改一个对象.这条规则适用于此吗?如果是的话,有没有办法在一行中以不同的方式表达这个习语?

如果一个人std::unique_ptr被鄙视取代std::auto_ptr怎么办?

c++ sequence-points move-semantics c++11

16
推荐指数
1
解决办法
1229
查看次数

其他线程是否会以相同的顺序看到两个对不同线程中相同位置的轻松写入?

在x86架构上,存储到同一内存位置的总订单有,例如,请参阅此视频.C++ 11内存模型有哪些保证?

更确切地说,在

-- Initially --
std::atomic<int> x{0};

-- Thread 1 --
x.store(1, std::memory_order_release);

-- Thread 2 --
x.store(2, std::memory_order_release);

-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);
int r2 = x.load(std::memory_order_acquire);

-- Thread 4 --
int r3 = x.load(std::memory_order_acquire);
int r4 = x.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)

结果r1==1, r2==2, r3==2, r4==1是否允许(在x86以外的某些架构上)?如果我要更换所有memory_order的东西std::memory_order_relaxed怎么办?

c++ concurrency memory-model c++11 stdatomic

14
推荐指数
2
解决办法
358
查看次数

可变参数模板的部分特化需要第一个非可变参数模板参数

以下代码

#include <iostream>
#include <utility>

template<typename F, typename... T>
struct Wrapper{ };

template<typename T>
struct is_wrapper : std::false_type {};

template<typename... T>
struct is_wrapper<Wrapper<T...>> : std::true_type {};

//template<typename F, typename... T>
//struct is_wrapper<Wrapper<F, T...>> : std::true_type {};

int main()
{
    Wrapper<int, double> w;

    std::cout << is_wrapper<decltype(w)>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

打印0.但是,如果取消注释中间的两行,则打印1.

为什么不总是打印1?第二部分专业化是否也应该涵盖显然仅由第三(评论)部分专业化所涵盖的案例?

c++ partial-specialization variadic-templates c++11

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

测试所有元素是否与C++ 17 fold-expression相同

我有一个函数采用可变参数包,在开始我想检查所有元素比较相等.我可以以某种方式使用新的C++ 17折叠表达式来简洁地编写一个单行程序吗?我刚在想

template<typename... Args>
void func (Args... args)
{
    ASSERT ((args == ...));

    // more code here...
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为它编译为首先正确比较后两个参数的代码,然后将第三个参数与第一个比较的结果进行比较,这是一个bool.这种类型的折叠表达式可能具有哪些用例(类似args < ...)?有没有机会我可以避免编写专用的递归模板来执行此操作?

c++ templates variadic-templates fold-expression c++17

10
推荐指数
2
解决办法
2266
查看次数

检查成员是否在课堂上宣布

是否可以检查给定类中是否声明了成员变量,成员函数或类型定义?

StackOverflow上的各种问题讨论了检查给定类是否只包含一个成员,主要是使用std :: is_detected.但是所有这些解决方案也在派生类中检测成员,这可能不会自己声明成员.

例如,以下内容无法编译.

#include <experimental/type_traits>

struct base
{
  using type = std::true_type;
};

struct derived : public base { };

template<typename T>
using has_type_t = typename T::type;

template<typename T>
constexpr inline bool has_type_v =         
std::experimental::is_detected<has_type_t, T>::value;

int main ()
{
  static_assert (has_type_v<base>);
  static_assert (!has_type_v<derived>);
}
Run Code Online (Sandbox Code Playgroud)

可以进行任何更改,以便两个断言成立吗?或者需要反思吗?

c++ sfinae type-traits c++17

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

控制台输出顺序会降低多线程程序的速度

编译以下代码时

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <mutex>

std::mutex cout_mut;

void task()
{
    for(int i=0; i<10; i++)
    {
        double d=0.0;
        for(size_t cnt=0; cnt<200000000; cnt++) d += 1.23456;

        std::lock_guard<std::mutex> lg(cout_mut);
        std::cout << d << "(Help)" << std::endl;
        //        std::cout << "(Help)" << d << std::endl;
    }
}

int main()
{
    std::vector<std::thread> all_t(std::thread::hardware_concurrency());

    auto t_begin = std::chrono::high_resolution_clock::now();

    for(auto& t : all_t) t = std::thread{task};
    for(auto& t : all_t) t.join();

    auto t_end = std::chrono::high_resolution_clock::now();

    std::cout << "Took : " << …
Run Code Online (Sandbox Code Playgroud)

concurrency mutex c++11 stdthread

8
推荐指数
1
解决办法
247
查看次数

将"this"指针传递给析构函数中的其他类/函数

在一些主对象的析构函数中在堆栈上创建一个worker-object并将master-object的this指针传递给helper-object 是合法的C++ 吗?然后,辅助对象还将调用主对象的成员函数或访问成员变量.

换句话说,是以下合法的C++?

struct MasterClass
{
  MasterClass (int data);

  ~MasterClass ();

  int data;
};

struct WorkerClass
{
  WorkerClass (MasterClass *m) : m (m) { }

  void do_some_work () { m->data = 42; }

  MasterClass *m;
};

MasterClass::MasterClass (int data)
: data (data)
{ }

MasterClass::~MasterClass ()
{
  WorkerClass w (this);

  w.do_some_work ();
}

int main ()
{
  MasterClass m (7);
}
Run Code Online (Sandbox Code Playgroud)

我知道,一旦析构函数开始执行,master-object的生命周期就会结束.但我认为在任何对象的析构函数中调用非虚拟成员函数是合法的,这些函数使用隐式this参数/参数.

c++ destructor this object-lifetime c++11

8
推荐指数
1
解决办法
608
查看次数

std ::搜索单程范围

我想从a读取,std::istream直到找到一定数量的字符,即,我想实现以下接口:

void read_until (std::istream &is, std::string_view needle);
Run Code Online (Sandbox Code Playgroud)

使用std::istreambuf_iterator,我相信这相当于std::search单通道迭代器的组合.不幸的是,std::boyer_moore_searcher需要随机访问迭代器.

使用C++标准库(以及与大小成比例的一点内存sv)是否有上述接口的简单实现,或者我是否必须自己编写代码?

c++ search iterator boyer-moore c++17

8
推荐指数
1
解决办法
171
查看次数

为什么std :: aligned_storage的分配总是有偏移量?

std::aligned_storage<2, 4096>::type在堆上分配一个时,我总是得到一个偏移16个字节的指针(在x64上;在x86上,它偏移8个字节).换句话说,这个:

#include <iostream>
#include <cstddef>

int main() {
    typedef std::aligned_storage<2, 4096>::type MemPage;

    MemPage* p_mp = new MemPage;

    std::cout << (void*)p_mp << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

给我(例如)

0x72f010
Run Code Online (Sandbox Code Playgroud)

虽然我希望最后三位数都为零.在std::aligned_storage<>::type堆栈上分配时,一切都按预期工作.

我在ubuntu 14.04上使用gcc-4.8.2 x86_64.

c++ gcc memory-alignment

7
推荐指数
1
解决办法
1094
查看次数

将float转换为double并返回float会在C++中给出相同的值

假设在以下代码中

float f1 = ...;
double d1 = static_cast<double>(f1);
float f2 = static_cast<float>(d1);

ASSERT( f1 == f2 );
Run Code Online (Sandbox Code Playgroud)

变量f1初始化为不是NaN的东西.那么断言是否保证符合C++标准?

c++ floating-point

7
推荐指数
1
解决办法
533
查看次数