如果数据结构中包含多个元素,则它的原子版本不能(始终)无锁.我被告知这对于较大的类型是正确的,因为CPU不能在不使用某种锁的情况下以原子方式更改数据.
例如:
#include <iostream>
#include <atomic>
struct foo {
double a;
double b;
};
std::atomic<foo> var;
int main()
{
std::cout << var.is_lock_free() << std::endl;
std::cout << sizeof(foo) << std::endl;
std::cout << sizeof(var) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出(Linux/gcc)是:
0
16
16
Run Code Online (Sandbox Code Playgroud)
由于原子和foo大小相同,我不认为锁存储在原子中.
我的问题是:
如果一个原子变量使用一个锁,它存储在哪里,这对该变量的多个实例意味着什么?
在我的 Fedora 34 环境(g++)中,std::accumulate定义为:
template<typename ITER, typename T>
constexpr inline T accumulate(ITER first, ITER last, T init)
{
for (; first != last; ++first)
init = std::move(init) + *first; // why move ?
return init;
}
Run Code Online (Sandbox Code Playgroud)
如果表达式init + *first已经是右值,那么 的目的是什么std::move?
我不明白为什么以下代码在GCC 8.0上编译:
decltype(auto) foo(int&& r) {
return r;
}
Run Code Online (Sandbox Code Playgroud)
在foo,声明类型r是int&&,所以返回类型foo也是int&&.但r它本身是一个左值,而左值不能绑定到右值引用.
我错过了什么吗?
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v{ 1, 2, 3, 4 };
std::for_each_n(v.begin(), 2, [](int n) { });
}
Run Code Online (Sandbox Code Playgroud)
使用 gcc 9.2.1 ( -std=c++17),编译失败:
error: could not convert 'std::for_each<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, main()::<lambda(int)> >(__first, __first.__gnu_cxx::__normal_iterator<int*, std::vector<int> >::operator+(__n2), (__f, main()::<lambda(int)>()))' from 'main()::<lambda(int)>' to '__gnu_cxx::__normal_iterator<int*, std::vector<int> >'
3900 | return std::for_each(__first, __first + __n2, __f);
Run Code Online (Sandbox Code Playgroud)
偷看里面for_each_n告诉我它叫
std::for_each(v.begin(), v.begin() + 2, ...)
但显然,for_each返回函数对象与for_each_n返回迭代器不兼容。
我如何使用for_each_n?
根据有关委托构造函数的问题,当第一个构造函数完成时,将调用析构函数。
\n这与下面的代码是一致的:
struct test {\n test() { std::cout << "default constr\\n"; }\n test(int) : test() { std::cout << "argument constr\\n"; throw int{}; }\n ~test() { std::cout << "destr\\n"; }\n};\n\nint main()\n{\n try {\n test t{3};\n } catch(...)\n {\n std::cout << "caught\\n";\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n输出:
\ndefault constr\nargument constr\ndestr\ncaught\nRun Code Online (Sandbox Code Playgroud)\n但是,Stroustrup 在他的书中(第 4 版,第 503 页)说了以下内容:
\n\n\n在对象的构造函数完成之前,对象不会被视为已构造 (...)。使用委托构造函数时,在委托构造函数完成\xe2\x80\x93 之前,对象不会被视为已构造,仅完成委托构造函数是不够的。除非其原始构造函数完成,否则不会为对象调用析构函数。\n
\n
是我误读了还是他有别的意思?
\n