私は1つのデバイスに機能を提供するためにライブラリをエンジニアリングしています。このデバイスにはいくつかの一般的な操作がありますが、これらの操作を実行するためのアルゴリズムは異なります。次のように言うのではなく、1つの特定の操作に対して1つの関数プロトタイプが必要です。
Alg1_Foo();
Alg2_Foo();
...
これ欲しい:
Foo(alg);
しかし、algを個別の引数として渡したくないのは、関数にはそれがなくても多くの引数があるため、デバイスの識別および/または承認のための引数、引数、引数(少なくとも1つ)が含まれるためです。 )なので、algを別の引数として追加するのは面倒だと思います。
だから私の考えはこのような解決策を提供することです:
Foo(const SomeUnion& some_union);
どこ:
union SomeUnion {
AlgId alg_id;
alg1::SomeStruct alg1_some_struct;
alg2::SomeStruct alg2_some_struct;
SomeUnion(alg1::SomeStruct some_struct) { alg1_some_struct = some_struct; };
SomeUnion(alg2::SomeStruct some_struct) { alg2_some_struct = some_struct; };
};
そして、特定のアルゴリズムの構造は次のようになります。
namespace alg1 {
struct SomeStruct {
static const AlgId alg_id = ALG1;
. . .
};
}
したがって、たとえばalg1を実行する場合は、適切な構造をFooに渡し、C++で機能します。
alg1::SomeStruct a;
Foo(a);
しかし、私は自分のライブラリに純粋なCの可能性を維持してもらいたいと思っています。もちろん、次のことを行う必要があります。
参照を削除し、ポインターに置き換えます。
名前空間を削除します(構造の助けを借りてそれらをエミュレートできます(このスレッドは興味のある人に役立つかもしれません:Cの名前空間);
構造体を定義するC++スタイルをCからのものに置き換え、タグ名前空間で名前も定義します(typedef struct tagStruct {...} Struct;);
内部構造とユニオンから関数を削除します。
でも、Cのメンテナンスでやりたいことができるかどうかはわかりませんが…道はわかりますか?または、alg_idを個別の引数として渡して、共用体や構造体に煩わされないようにする方が簡単ですか(ただし、可能であれば避けたいと思います)。