c++ std:: atomic: fetch или не реализован?


С этим отрывком кода:

class myclass {
    volatile std::atomic<bool> flag;
    public:
    myclass(): flag(false) {}
    bool get_flag() { return flag; }
    bool try_set() {
        return !flag.fetch_or(flag, true);
    }
    void reset() {
        flag = false;
    }
};

У меня есть эта ошибка компиляции:

error: ‘volatile struct std::atomic<bool>’ has no member named ‘fetch_or’   
   return !flag.fetch_or(flag, true);

Он компилируется, если, Однако, я изменяю параметр шаблона на int:

class myclass {
    volatile std::atomic<int> flag;
    public:
    myclass(): flag(0) {}
    bool get_flag() { return flag; }
    bool try_set() {
        return !flag.fetch_or(flag, true);
    }
    void reset() {
        flag = 0;
    }
};

Ссылкаatomic говорит, что "полная специализация atomic<bool>" трактуется как "неспециализированная", что я считаю источником проблем. Итак, мои сомнения:

  1. как "полный специализацией" быть "рассматривается как неспециализированная"?
  2. пусть там я столкнусь с какими-нибудь хитрыми ловушками использование в качестве параметра шаблона флага int вместо bool при вызове flag.fetch_or()?

Я использую gcc 5.1.0 и компилирую с -std=c++14.

1 3

1 ответ:

ПроектC++11 N3337 не требует этого метода для bool.

29.5 "атомарные типы"

template <class T> struct atomic {
  [...]
}

template <> struct atomic<integral> {
  [...]
  integral fetch_or(integral , memory_order = memory_order_seq_cst) noexcept;
  [...]
}

29.5/1:

Семантика операций по специализациям атомного определяются в 29.6.

29.6.3 / 2 "арифметические операции над атомарными типами":

В объявлениях этих функций и специализациях шаблонов функций имя integral относится к интегральному типу, а имя atomic-integral-к любому из них. атомарный или к именованному базовому классу для интеграла из таблицы 145 или выводимого из таблицы 146.

И таблица 145 не содержит bool.

Таким образом, только интегральные (без bool) специализации struct будут иметь этот метод. Это немного сбивает с толку, потому что в остальной части стандарта "интегральные типы" включают bool, 3.9.1 / 7 "фундаментальные типы":

Типы bool, char, char16_t, char32_t, wchar_t, а также знаковые и беззнаковые целочисленные типы являются коллективными называются интегральными типами. Синонимом интегрального типа является целочисленный тип.