現在、マイクロコントローラー用のRTOSを書いています。全体がC ++ 11で書かれています-誰かが興味を持っていて、リポジトリへのリンクが一番下にある場合。
現在私は、スレッド間(または、割り込みハンドラーとスレッド間、または割り込みハンドラーと他の割り込みハンドラー間)でオブジェクトを受け渡すための単純なデータキューであるクラスを作成しています。通常、私は他のプロジェクトにあるいくつかの共通のAPIを追跡しようとすると、まだ私は持っている同時キューのいずれかの例が見つかりませんでしたemplace()
機能とサポートタイムアウトを。
私の一般的な「問題」は、次の2つのインターフェースを決定できないことです。
(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>);
...
}
2番目のバージョン:
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
サフィックスが付いたこれらの関数の2番目のセットがあります-これらは期間ではなくタイムポイントを使用します)
最初のバージョンは、タイムアウトを最後のパラメーターとして持つ「一般的なスタイル」に従います(例は、POSIXメッセージキュー、std::condition_variable
マイクロコントローラー用の任意のRTOSのシンプルキューです)。問題は、このタイムアウト引数をtryEmplaceFor()関数の最後の引数にすることはできないことです。可変テンプレートの場合、既知の引数が最初(*)でなければならないためです。したがって、2番目のバージョンは「一貫性がある」-タイムアウトのあるすべての関数は、最初の引数としてタイムアウトを持ちます。このバリアントには、そのような機能の最初の引数としてタイムアウトを設定した最初の例であるという明らかな問題があります。
OSにより良いサービスを提供するインターフェイス:
- 最後の引数としてタイムアウトを持つという確立された標準(
tryEmplaceFor()
およびtryEmplaceUntil()
- を除いて-最初の引数(*)でなければなりません)? - 一貫性-タイムアウトを最初の引数にしたいですか?
(*) -私はそれを知っている技術的に私はのための最後の引数としてタイムアウトを持つことができtryEmplaceFor()
そしてtryEmplaceUntil()
、私はむしろ、このような単純なシナリオのようなテンプレートの魔法を使用しないようしたい-ちょうど最後の引数は、ビット行き過ぎ思える取得するために、これらすべての再帰的なインスタンス化をやって、特に、ユーザーが何か間違った場合にコンパイラーが生成するエラーを視覚化すると...