请考虑以下代码片段摘自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) 这是一些示例代码:
#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) 请考虑以下代码段.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.
请考虑以下代码.
#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.
我无法形成关于控制流如何与spawn发生的心理图像.
当我调用时spawn(io_service, my_coroutine),它是否为io_service队列添加了一个新的处理程序来包装对my_coroutine?的调用?
在协同程序中我调用异步函数传递它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++ 11与使用C++ 11编译器构建的最新版Boost(比如说1.55)之间的互操作性程度如何?
根据这份文件:
http://www.stroustrup.com/terminology.pdf
关于这些,我有几个问题.
一个.具有身份的x值的例子是什么?以下是不合法的:
Foo f;
&std::move(f);
Run Code Online (Sandbox Code Playgroud)
湾 我可以重载类Foo的& -运算符,并使其返回这使以下成为合法的:
&Foo(5);
Run Code Online (Sandbox Code Playgroud)
但像Foo(5)这样的公关价值不具备同一性.还是对身份有更微妙的解释?
我见过用过:
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)
允许这个标准的相关部分是什么?
我试图了解以下代码段的行为.我特别关注的是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 …
为什么公共构造函数(和析构函数)不足以将类型的对象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调用默认构造函数.
我想写这样的代码:
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)
我知道功能模板不允许使用模板模板参数.但还有另一种方法可以达到同样的效果吗?
假设我有来自各个农场的苹果。所以树结苹果,农场有树。我想要一份苹果列表,其中还包含对它们来自的农场的引用。
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) 我正在尝试这样的事情:
\n\nclass 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};\nRun Code Online (Sandbox Code Playgroud)\n\n现在我有一个列表,我通过 emplace 将它们插入其中,我正在尝试做这样的事情。
\n\nstd::list<MyClass> lst;\nstd::remove_if(lst.begin(), lst.end(), [&,this](MyClass& mcl) { return mcl.is_foo();});\nRun Code Online (Sandbox Code Playgroud)\n\n在 gcc 4.6.x 上,我不断收到此错误:
\n\nIn 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++ ×11
c++11 ×7
boost ×4
templates ×2
boost-asio ×1
declaration ×1
fiber ×1
fibers ×1
gcc ×1
graph ×1
gremlin ×1
memory-model ×1
move ×1
ruby ×1
rvalue ×1
scoped-ptr ×1
stdvector ×1
stl ×1
titan ×1
xvalue ×1