我在cpp中得到了这段代码(这是我得到错误的一个最小示例):
#include <cstdio>
#include <functional>
#include <iostream>
#include <atomic>
const int N = 128;
template <typename T> struct Element {
const T * key{nullptr};
bool occupied{false};
Element( const T* key, bool occupied ) : key( key ), occupied( occupied ) {}
Element() : key{}, occupied{} {}
};
template <typename T>
class AtomicHashSet {
std::atomic<Element<T>> table[N];
public:
AtomicHashSet() : table{} {}
size_t hash( const T& key ) const {
return std::hash<const T>()( &key );
}
bool insert( const T& key ) {
Element<T> e{};
e.key = &key;
e.occupied = true;
for ( size_t i = 0; i < N; ++i ) {
size_t idx = ( hash( key ) + i ) % N;
Element<T> empty{};
if ( table[idx].compare_exchange_strong( empty, e ) ) {
return true;
}
else if ( table[idx].load().key == &key ) {
return false;
}
}
return false;
}
};
int main() {
AtomicHashSet<int> set;
int one = 1;
std::cout << "insert hello 1: " << set.insert(one) << std::endl;
return 0;
}错误显示如下:
error: use of deleted function ‘std::atomic<_Tp>::atomic() [with _Tp = Element<int>]’
AtomicHashSet() : table{} {}我之前在不同的行处遇到了同样的错误,因为我忘记了'Element‘结构中的默认构造函数。这一次我做错了什么?
有人能帮帮我吗?非常感谢!
发布于 2016-11-29 06:38:34
错误消息令人困惑。但问题是,除了之外,原子的构造函数被声明为,而您的元素的构造函数没有声明,所以它不能被调用。如果你在元素的构造函数中添加了noexcept,它将会被编译:
Element() noexcept : key{}, occupied{} {}发布于 2016-11-29 08:12:25
std::atomic's default constructor是noexcept,所以当您尝试用某个类型实例化它时,该类型也需要是noexcept默认可构造的,以便异常规范匹配。
Element( const T* key, bool occupied ) noexcept : key( key ), occupied( occupied ) {}
Element() noexcept : key{}, occupied{} {}我会将你的第二个构造函数重写为
Element() noexcept = default; // noexcept is optional here下一个问题是你的这段奇怪的代码
return std::hash<const T>()( &key );
^^^^^ ^^^^std::hash没有为const类型提供专门化,并且您正在将int const *传递给需要int的函数。将上一行重写为
return std::hash<T>()( key );进行这些更改后,您将遇到以下链接器错误
undefined reference to `__atomic_load_16'正如在this answer中所解释的,要允许gcc为16字节的原子比较交换生成指令,您需要将-mcx16传递给编译器。或者,您可以传递一个-march选项,例如,-march=native,如果编译此代码的机器支持该指令,该选项将生成该指令。
Live demo
https://stackoverflow.com/questions/40854566
复制相似问题