繁体   English   中英

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

[英]error: use of deleted function ‘std::atomic<_Tp>::atomic()

我在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'结构中的默认构造函数。 这次我错了什么?

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

std::atomic的默认构造函数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'

如此答案中所述 ,要允许gcc生成用于16字节原子比较交换的指令,您需要将-mcx16传递给编译器。 另外,您可以传递-march选项,例如-march=native ,如果您要在其上编译此代码的计算机支持该指令,它将生成指令。

现场演示

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM