С этой выдержкой из кода:
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<bool>
«рассматривается как» неспециализированная «, что я считаю источником проблем. Поэтому мои сомнения:
int
вместо bool
при звонке flag.fetch_or()
?Я использую GCC 5.1.0, и компилирую с -std=c++14
,
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 «Арифметические операции над атомными типами»:
В объявлениях этих функций и специализаций шаблонов функций интеграл имени относится к целочисленному типу, а атомный интеграл имени относится либо к атомарному, либо к названному базовому классу для интеграла из таблицы 145 или из таблицы 146.
и таблица 145 не содержит bool
,
Так что только интеграл (без bool
) специализации struct
будет иметь этот метод.
Это немного сбивает с толку, потому что в остальной части стандарта «целочисленные типы» включают в себя bool, 3.9.1 / 7 «Основные типы»:
Типы bool, char, char16_t, char32_t, wchar_t, а также целочисленные типы со знаком и без знака вместе называются целочисленными типами. Синоним для целочисленного типа — целочисленный тип.