Я сейчас пишу ОСРВ для микроконтроллеров. Все написано на C ++ 11 - если кому-то интересно, а ссылка на репозиторий находится внизу.
В настоящее время я пишу класс, который представляет собой простую очередь данных для передачи объектов между потоками (или между обработчиками прерываний и потоками или обработчиками прерываний и другими обработчиками прерываний). Обычно я пытаюсь следовать некоторым распространенным API, встречающимся в других проектах, но я не нашел ни одного примера параллельной очереди с emplace()
функцией AND, поддерживающей тайм-ауты.
Моя общая «проблема» заключается в том, что я не могу выбрать между этими двумя интерфейсами:
( std::chrono::duration<Rep, Period>
это шаблонный тип, для ясности я опускаю шаблонный шаблон)
Первая версия:
template<typename T>
class FifoQueue
{
public:
...
template<typename... Args>
int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
int tryPopFor(T&, std::chrono::duration<Rep, Period>);
int tryPushFor(const T&, std::chrono::duration<Rep, Period>);
int tryPushFor(T&&, std::chrono::duration<Rep, Period>);
...
}
Вторая версия:
template<typename T>
class FifoQueue
{
public:
...
template<typename... Args>
int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
int tryPopFor(std::chrono::duration<Rep, Period>, T&);
int tryPushFor(std::chrono::duration<Rep, Period>, const T&);
int tryPushFor(std::chrono::duration<Rep, Period>, T&&);
...
}
(будет второй набор этих функций с ...Until
суффиксом - они будут использовать точку времени вместо продолжительности)
Первая версия следует «общему стилю», когда таймаут является последним параметром (например, очереди сообщений POSIX, std::condition_variable
простые очереди в любой ОСРВ для микроконтроллеров). Проблема в том, что этот аргумент тайм-аута не может быть последним для функции tryEmplaceFor (), потому что в случае шаблонов с переменным числом аргументов «известные» аргументы должны быть первыми (*). Таким образом, вторая версия является «последовательной» - все функции с тайм-аутом имеют тайм-аут в качестве первого аргумента. Этот вариант имеет очевидную проблему, являющуюся, вероятно, первым примером наличия таймаута в качестве первого аргумента для такой функциональности.
Какой интерфейс будет лучше обслуживать ОС:
- установленный стандарт наличия таймаута в качестве последнего аргумента (за исключением
tryEmplaceFor()
иtryEmplaceUntil()
- где он должен быть первым аргументом (*))? - последовательность - предпочесть таймаут в качестве первого аргумента?
(*) - Я знаю, что технически у меня мог бы быть тайм-аут в качестве последнего аргумента для tryEmplaceFor()
и tryEmplaceUntil()
, но я бы предпочел не использовать такую магию шаблона для такого простого сценария - выполнение всех этих рекурсивных реализаций только для того, чтобы получить последний аргумент, кажется немного излишним, особенно когда я визуализирую ошибки, которые выдает компилятор, если пользователь делает что-то не так ...