错误:使用已删除的函数'std :: atomic< _Tp> :: atomic()

时间:2016-11-28 22:21:49

标签: c++ c++14

我在cpp中得到了这个代码(这是我收到错误的最小例子):

# Initialize to zero length
_code = ""
while len(_code) != 5:
    # Executed each time at beginning of `while`
    _code = str(input('Enter your post code: '))
    if  len(_code) > 5:
        print("too long")
    elif len(_code) < 5:
        print("too short")
print('post code is: ' + str(_code))

错误显示如下:

#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;
}

我在另一行之前遇到了同样的错误,因为我忘记了'Element'结构中的默认构造函数。这次我错了什么?

有人可以帮助我吗?非常感谢!

2 个答案:

答案 0 :(得分:2)

std::atomic's default constructornoexcept,因此当您尝试使用某种类型对其进行实例化时,该类型也必须是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

答案 1 :(得分:1)

错误消息令人困惑。 但问题是原子的构造函数声明为 noexcept ,而Element的构造函数不是,因此无法调用。 如果将noexcept添加到Element的构造函数中,它将编译:

Element() noexcept : key{}, occupied{} {}