首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:使用已删除的函数‘std::atomic<_Tp>::atomic()

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

Stack Overflow用户
提问于 2016-11-29 06:21:49
回答 2查看 3.1K关注 0票数 2

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

代码语言:javascript
复制
#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;
}

错误显示如下:

代码语言:javascript
复制
error: use of deleted function ‘std::atomic<_Tp>::atomic() [with _Tp = Element<int>]’
     AtomicHashSet() : table{} {}

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

有人能帮帮我吗?非常感谢!

EN

回答 2

Stack Overflow用户

发布于 2016-11-29 06:38:34

错误消息令人困惑。但问题是,除了之外,原子的构造函数被声明为,而您的元素的构造函数没有声明,所以它不能被调用。如果你在元素的构造函数中添加了noexcept,它将会被编译:

代码语言:javascript
复制
Element() noexcept : key{}, occupied{} {}
票数 3
EN

Stack Overflow用户

发布于 2016-11-29 08:12:25

std::atomic's default constructornoexcept,所以当您尝试用某个类型实例化它时,该类型也需要是noexcept默认可构造的,以便异常规范匹配。

代码语言:javascript
复制
Element( const T* key, bool occupied ) noexcept : key( key ), occupied( occupied ) {}
Element() noexcept : key{}, occupied{} {}

我会将你的第二个构造函数重写为

代码语言:javascript
复制
Element() noexcept = default;  // noexcept is optional here

下一个问题是你的这段奇怪的代码

代码语言:javascript
复制
return std::hash<const T>()( &key );
                 ^^^^^       ^^^^

std::hash没有为const类型提供专门化,并且您正在将int const *传递给需要int的函数。将上一行重写为

代码语言:javascript
复制
return std::hash<T>()( key );

进行这些更改后,您将遇到以下链接器错误

代码语言:javascript
复制
undefined reference to `__atomic_load_16'

正如在this answer中所解释的,要允许gcc为16字节的原子比较交换生成指令,您需要将-mcx16传递给编译器。或者,您可以传递一个-march选项,例如,-march=native,如果编译此代码的机器支持该指令,该选项将生成该指令。

Live demo

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40854566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档