我打算声明一个原子变量向量,用作多线程程序中的计数器.这是我尝试过的:
#include <atomic>
#include <vector>
int main(void)
{
std::vector<std::atomic<int>> v_a;
std::atomic<int> a_i(1);
v_a.push_back(a_i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是gcc 4.6.3的烦人冗长的错误信息:
In file included from /usr/include/c++/4.6/x86_64-linux-gnu/./bits/c++allocator.h:34:0,
from /usr/include/c++/4.6/bits/allocator.h:48,
from /usr/include/c++/4.6/vector:62,
from test_atomic_vec.h:2,
from test_atomic_vec.cc:1:
/usr/include/c++/4.6/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, const _Tp&) [with _Tp = std::atomic<int>, __gnu_cxx::new_allocator<_Tp>::pointer = std::atomic<int>*]’:
/usr/include/c++/4.6/bits/stl_vector.h:830:6: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::atomic<int>, _Alloc = std::allocator<std::atomic<int> >, std::vector<_Tp, _Alloc>::value_type = std::atomic<int>]’
test_atomic_vec.cc:10:20: instantiated from here
/usr/include/c++/4.6/ext/new_allocator.h:108:9: error: use of deleted function ‘std::atomic<int>::atomic(const std::atomic<int>&)’
/usr/include/c++/4.6/atomic:538:7: error: declared …
Run Code Online (Sandbox Code Playgroud) 在Visual Studio 2013(版本12.0.31101.00 Update 4)中编译此代码段时没有错误
class A
{
public:
A(){}
A(A &&){}
};
int main(int, char*)
{
A a;
new A(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然它在Visual Studio 2015 RC(版本14.0.22823.1 D14REL)中使用此错误进行编译:
1>------ Build started: Project: foo, Configuration: Debug Win32 ------
1> foo.cpp
1>c:\dev\foo\foo.cpp(11): error C2280: 'A::A(const A &)': attempting to reference a deleted function
1> c:\dev\foo\foo.cpp(6): note: compiler has generated 'A::A' here
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)
我认为Visual Studio 2015附带的编译器生成了复制构造函数并将其标记为=delete
,因此我得到了错误C2280(顺便说一句,我在msdn.microsoft.com上找不到文档).
现在,假设我有一个可与Visual Studio 2013兼容的代码库(它可以工作,因为它依赖于编译器自动生成的代码)但由于C2280而无法与Visual Studio …
std::atomic
删除了复制赋值运算符。因此,以下结果会导致编译器错误:
std::atomic<int> a1, a2;
a1 = a2; // Error
Run Code Online (Sandbox Code Playgroud)
我认为删除运算符的动机已在这篇文章中进行了解释。到目前为止,一切都很好。但我注意到,添加volatile
会导致代码突然编译(在godbolt上运行):
volatile std::atomic<int> a1, a2;
a1 = a2; // OK
Run Code Online (Sandbox Code Playgroud)
我的项目并不真正需要volatile
变量,所以这只是出于好奇:这是 C++ 标准中的疏忽,还是故意的(为什么?)?
注意:我可以通过修改定义来得到编译器错误std::atomic
,或者通过添加
atomic & operator=(const volatile atomic &) volatile = delete;
Run Code Online (Sandbox Code Playgroud)
或者通过删除转换运算符 operator T() const volatile noexcept
。
我有一个原子成员的类,我想写一个复制构造函数:
struct Foo
{
std::atomic<int> mInt;
Foo() {}
Foo(const Foo& pOther)
{
std::atomic_store(mInt, std::atomic_load(pOther.mInt, memory_order_relaxed), memory_order_relaxed);
}
};
Run Code Online (Sandbox Code Playgroud)
但我不知道我必须使用哪种顺序,因为我不知道将在何时何地调用此复制构造函数.
我可以使用relaxed
复制构造函数和赋值运算符的顺序吗?
我正在研究Java库的C++端口.其中一个问题是我无法找到Java的AtomicLongArray.任何人都知道c ++ 11中是否有任何相同的东西或者如何实现类似的功能?我看过C++ 11原子但找不到任何东西.