Летучие объекты типа std :: chrono :: duration - PullRequest
0 голосов
/ 03 октября 2018

У меня есть программа, которая использует std::chrono::duration объекты с квалификацией volatile.По-видимому, такие объекты становятся очень сложными в использовании.Например, следующая простая программа выдает ошибку компиляции (на gcc и clang):

#include <chrono>

volatile std::chrono::nanoseconds s;

void foo(std::chrono::nanoseconds k) {
    s = k;
}

error: передача 'volatile наносекунд' {aka 'volatile std :: chrono :: duration>'} какАргумент 'this' отбрасывает квалификаторы [-fpermissive]

. Очевидно, почему у меня есть эта ошибка с учетом интерфейса класса, и я также знаю, как заставить ее "работать" (undefined-поведение)мудро) с const_cast.

Сказав это, может ли отсутствие квалифицированных летучих членов std::chrono::duration считаться дефектом?В конце концов, volatile является совершенно законной конструкцией C ++, и, хотя она используется редко, имеет свои приложения.

PS Я бы хотел оставить мудрость изменчивой квалификации вне этого вопроса, но мой хрустальный шарговорит мне, что это не так, поэтому для вытеснения всех мантр «вам не нужен volatile, потому что это не поточно-ориентированный», давайте рассмотрим случай обработчика сигнала.

1 Ответ

0 голосов
/ 03 октября 2018

За исключением очень объектов низкого уровня, std :: lib на самом деле вообще не работает с volatile.Можно утверждать, что chrono является настолько низким уровнем, что должен обрабатывать volatile квалификации.Я не знаю, купит ли комитет этот аргумент или нет.

Можно обойти такие ограничения.Вы упомянули const_cast.Я бы порекомендовал приводить назад и вперед от базового целочисленного типа.Это одно из немногих обстоятельств, когда я рекомендую это делать.И это может быть заключено в небольшую функцию:

#include <chrono>

volatile std::chrono::nanoseconds::rep s;

void
set_s(std::chrono::nanoseconds k)
{
    s = k.count();
}

std::chrono::nanoseconds
get_s()
{
    return std::chrono::nanoseconds{s};
}

void foo(std::chrono::nanoseconds k) {
    set_s(k);
}
...