小编Cpp*_*oob的帖子

memory_order_relaxed如何在智能指针中增加原子引用计数?

请考虑以下代码片段摘自Herb Sutter关于原子的讨论:

smart_ptr类包含一个名为control_block_ptr的pimpl对象,其中包含引用计数refs.

// Thread A:
// smart_ptr copy ctor
smart_ptr(const smart_ptr& other) {
  ...
  control_block_ptr = other->control_block_ptr;
  control_block_ptr->refs.fetch_add(1, memory_order_relaxed);
  ...
}

// Thread D:
// smart_ptr destructor
~smart_ptr() {
  if (control_block_ptr->refs.fetch_sub(1, memory_order_acq_rel) == 0) {
    delete control_block_ptr;
  }
}
Run Code Online (Sandbox Code Playgroud)

Herb Sutter说,线程A 中引用的增量可以使用memory_order_relaxed,因为"没有人根据动作做任何事情".现在我理解memory_order_relaxed,如果refs在某个时刻等于N ,则两个线程A和B执行以下代码:

control_block_ptr->refs.fetch_add(1, memory_order_relaxed);
Run Code Online (Sandbox Code Playgroud)

然后可能会发生两个线程都认为refs的值为N并且都将N + 1写回它.这显然不起作用,memory_order_acq_rel应该像析构函数一样使用.我哪里错了?

编辑1:考虑以下代码.

atomic_int refs = N; // at time t0. 

// [Thread 1]
refs.fetch_add(1, memory_order_relaxed); // at time t1. 

// [Thread 2]
n = …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading memory-model c++11 relaxed-atomics

12
推荐指数
1
解决办法
3547
查看次数

在C++中,哪些类别(左值,右值,右值等)可以生成类类型临时的表达式?

这是一些示例代码:

#include <iostream>

class Foo
{
public:
  explicit Foo(int x) : data(x) {};

  Foo& operator++()
  {
    data += 1;
    return *this;
  }

  void *get_addr()
  {
    return (void*)this;
  }

  friend Foo operator + (const Foo& lhs, const Foo& rhs);
  friend std::ostream& operator << (std::ostream& os, const Foo& f);

private:
  int data;
};

std::ostream& operator << (std::ostream& os, const Foo& f)
{
  return (os << f.data);
}

Foo operator + (const Foo& lhs, const Foo& rhs)
{
  return Foo(lhs.data + rhs.data);
} …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue rvalue-reference xvalue c++11

9
推荐指数
2
解决办法
1313
查看次数

什么时候被认为是完整的?

请考虑以下代码段.boost :: scoped_ptr的析构函数在main函数的末尾调用.析构函数使用boost :: checked_delete来解除分配封装的Widget指针.

#include <boost/scoped_ptr.hpp>
#include <iostream>

class Widget;
Widget *make_widget();

int main()
{  
  boost::scoped_ptr<Widget> sp(make_widget());
  // std::cout << sizeof(Widget) << std::endl;
}

class Widget
{
public:
  Widget() {}
  ~Widget() { std::cout << "Widget destructor called." << std::endl; }
};

Widget *make_widget()
{
  return new Widget;
}
Run Code Online (Sandbox Code Playgroud)

我希望这段代码无法编译,因为类Widget在scoped_ptr<Widget>调用析构函数时是不完整的.但是,这可以在g ++ 4.8和Visual Studio 2010上完全编译.请注意带有sizeof(Widget)main函数中表达式的注释语句.如果我取消注释它,它将无法编译暗示Widget在那一点必须是不完整的.

这种行为的正确解释是什么?

编辑:一些答案(现已删除)指向未定义的行为,但我希望在scoped_ptr析构函数中使用checked_delete 导致编译失败.FWIW,我正在使用Boost 1.55.

c++ boost smart-pointers scoped-ptr incomplete-type

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

boost :: stable_vector的容量成员函数不返回分配的容量

请考虑以下代码.

#include <string>
#include <boost/container/stable_vector.hpp>
#include <iostream>

int main()
{
  boost::container::stable_vector<std::string> vec;
  vec.reserve(10);
  std::cout << "capacity = " << vec.capacity() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

在运行它(在g ++/Linux上)时,输出是:

capacity = 4294967286(即2 ^ 32 - 10)

如果我用上面的std :: vector替换boost :: container :: stable_vector,则输出为:

容量= 10

我知道它也可能是容量= 20,或容量= 64或其他什么,但这仍然是理智的行为.

对于stable_vector,capacity()返回的内容似乎是(2 ^ 32 - N),N是调用reserve()时请求的容量.我没有在文档中看到这样的容量定义:http://www.boost.org/doc/libs/1_56_0/doc/html/boost/container/stable_vector.html#idp33067968-bb.

c++ boost stl

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

boost :: asio :: spawn有什么作用?

我无法形成关于控制流如何与spawn发生的心理图像.

  1. 当我调用时spawn(io_service, my_coroutine),它是否为io_service队列添加了一个新的处理程序来包装对my_coroutine?的调用?

  2. 在协同程序中我调用异步函数传递它yield_context,它是否暂停协程直到异步操作完成?

    void my_coroutine(yield_context yield)
    {
      ...
      async_foo(params ..., yield);
      ...   // control comes here only once the async_foo operation completes
    }

我不明白的是我们如何避免等待.假设如果my_coroutine服务于TCP连接,my_coroutine在特定实例上挂起的其他实例如何被挂起,等待async_foo完成?

c++ boost boost-asio boost-coroutine

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

Boost和C++之间的互操作性11

C++ 11与使用C++ 11编译器构建的最新版Boost(比如说1.55)之间的互操作性程度如何?

  1. 任何库功能的行为是否会根据我是否使用c ++ 11标志构建库来改变?
  2. lambda函数等语言特性如何与Boost的lambdas合作?

c++ boost c++11

6
推荐指数
1
解决办法
598
查看次数

说xvalues有身份并可移动是否正确?

根据这份文件:

http://www.stroustrup.com/terminology.pdf

  1. l值具有同一性并且不可移动.
  2. 公关值是可移动的,但没有身份.
  3. x值具有同一性并且是可移动的.

关于这些,我有几个问题.

一个.具有身份的x值的例子是什么?以下是不合法的:

Foo f;
&std::move(f);
Run Code Online (Sandbox Code Playgroud)

湾 我可以重载类Foo的& -运算符,并使其返回使以下成为合法的:

&Foo(5);
Run Code Online (Sandbox Code Playgroud)

但像Foo(5)这样的公关价值不具备同一性.还是对身份有更微妙的解释?

c++ rvalue-reference c++11

5
推荐指数
2
解决办法
594
查看次数

在参数列表中声明一个不完整的类型模板参数

我见过用过:

boost::error_info<struct tag_name, std::string> name_info;
Run Code Online (Sandbox Code Playgroud)

这里tag_name命名一个不完整的类型,struct它之前的关键字似乎就地声明它,而不是稍微冗长:

struct tag_name;
boost::error_info<tag_name, std::string> name_info;
Run Code Online (Sandbox Code Playgroud)

允许这个标准的相关部分是什么?

c++ templates declaration language-lawyer

5
推荐指数
1
解决办法
325
查看次数

红宝石纤维:恢复转移的纤维

我试图了解以下代码段的行为.我特别关注的是Fiber#transfer方法.

require 'fiber'

fiber2 = nil

fiber1 = Fiber.new do
  puts "In Fiber 1"                 # 3
  fiber2.transfer                   # 4
end

fiber2 = Fiber.new do
  puts "In Fiber 2"                  # 1
  fiber1.transfer                    # 2
  puts "In Fiber 2 again"            # 5
  Fiber.yield                        # 6
  puts "Fiber 2 resumed"             # 10
end

fiber3 = Fiber.new do
  puts "In Fiber 3"                  # 8
end

fiber2.resume                        # 0
fiber3.resume                        # 7
fiber2.resume                        # 9
Run Code Online (Sandbox Code Playgroud)

我已经编写了代码行,并在右侧执行了预期的执行顺序.一旦fiber3.resume返回并且我打电话fiber2.resume,我希望执行继续在fiber2标记为#10 …

ruby fiber fibers

5
推荐指数
1
解决办法
191
查看次数

为什么要在向量末端放置一个类型T需要移动可构造?

为什么公共构造函数(和析构函数)不足以将类型的对象T放在向量的后面?以下片段格式不正确.

#include <vector>

struct Foo {
  Foo() {}
  Foo(int) {}
  ~Foo() {}

  Foo(const Foo&) = delete;
  Foo& operator=(const Foo&) = delete;
};

int main() {
  std::vector<Foo> vfoo(10);

  vfoo.emplace_back();
}
Run Code Online (Sandbox Code Playgroud)

emplace_back要求,Foo至少可以移动构造的,而这个代码无法编译,因为移动构造函数与拷贝构造函数一起被删除.但我想像emplace_back使用placement new调用默认构造函数.

c++ move stdvector move-semantics c++11

2
推荐指数
1
解决办法
125
查看次数

模板模板参数与函数模板的等效行为

我想写这样的代码:

template <typename K, typename T, template <typename, typename> class C>
boost::optional<T> search(const C<K, T>& dict,
                          const K& key)
{
  auto it = dict.find(key);

  if (it != dict.end()) {
    return it->second;
  } else {
    return boost::none;
  }
}
Run Code Online (Sandbox Code Playgroud)

希望能够(std::[unordered_][multi]map)使用字典界面在各种容器上调用上述函数,如:

std::map<std::string, Foo> strToFoo;
auto val = search(strToFoo);
Run Code Online (Sandbox Code Playgroud)

我知道功能模板不允许使用模板模板参数.但还有另一种方法可以达到同样的效果吗?

c++ templates template-templates c++11 boost-optional

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

Gremlin:如何合并遍历路径上遇到的两个对象的选定属性

假设我有来自各个农场的苹果。所以树结苹果,农场有树。我想要一份苹果列表,其中还包含对它们来自的农场的引用。

g = new TinkerGraph();

// apples
a1 = g.addVertex("a1");
a1.setProperty("type", "apple");

a2 = g.addVertex("a2");
a2.setProperty("type", "apple");

a3 = g.addVertex("a3");
a3.setProperty("type", "apple");


// trees
t1 = g.addVertex("t1");
t1.setProperty("type", "tree");

t2 = g.addVertex("t2");
t2.setProperty("type", "tree");


// farms
f1 = g.addVertex("f1");
f1.setProperty("type", "farm");
f1.setProperty("uid", "f1");

f2 = g.addVertex("f2");
f2.setProperty("type", "farm");
f2.setProperty("uid", "f2");

g.addEdge(t1, a1, "bears");
g.addEdge(t1, a2, "bears");
g.addEdge(t2, a3, "bears");

g.addEdge(f1, t1, "has");
g.addEdge(f2, t2, "has");
Run Code Online (Sandbox Code Playgroud)

我想遍历图表来报告每个苹果,并在其中包含农场 ID。我尝试过这样的事情:

g.V.has("type", "apple").copySplit(_().in("bears").in("has").map("uid"),
                                  _().map()).fairMerge
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

==>{uid=f1}
==>{type=apple}
==>{uid=f1}
==>{type=apple}
==>{uid=f2}
==>{type=apple}
Run Code Online (Sandbox Code Playgroud)

我想要的是:

==>{uid=f1, type=apple} …
Run Code Online (Sandbox Code Playgroud)

graph graph-traversal gremlin titan property-graph

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

在 value_type 可移动但不可复制的列表上调用 std::remove_if

我正在尝试这样的事情:

\n\n
class MyClass\n{\npublic:\n explicit MyClass(int) {...};\n MyClass(MyClass&& that) { swap(that); }\nprivate:\n MyClass(const MyClass&); // disabled, pre-C++11 syntax\n MyClass& operator=(const MyClass&); // disabled, pre-C++11 syntax\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我有一个列表,我通过 emplace 将它们插入其中,我正在尝试做这样的事情。

\n\n
std::list<MyClass> lst;\nstd::remove_if(lst.begin(), lst.end(), [&,this](MyClass& mcl) { return mcl.is_foo();});\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 gcc 4.6.x 上,我不断收到此错误:

\n\n
In file included from /usr/include/c++/4.6/algorithm:63:0,\n             from simple_file_cache.cpp:5:\nfile_cache_entry.h: In function \xe2\x80\x98_FIter std::remove_if(_FIter, _FIter, _Predicate)   \n[with_FIter = std::_List_iterator<MyClass>, _Predicate = \nAnotherClass::foo_bar(std::tuple<unsigned int, unsigned int>)::<lambda(MyClass&)>]\xe2\x80\x99:\nanotherclass.cpp:225:11:   instantiated from here\nanotherclass.h:68:18: error: \xe2\x80\x98MyClass& MyClass::operator=(const MyClass&)\xe2\x80\x99 is private\n/usr/include/c++/4.6/bits/stl_algo.h:1149:13: error: within this context\nmake: *** …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++11

0
推荐指数
1
解决办法
720
查看次数