2012-05-14 32 views
5

行列や四元数など、複雑な入力を提供するC++ライブラリを開発しています。私はこれらのタイプを再実装する必要はないので、 は内部的にEigenライブラリを使用します。C++ライブラリのAPIでサードパーティの型を公開する必要があります

私はこれらのタイプをライブラリの クライアントに公開する最良の方法を決定しようとしています。私のAPIにはいくつかのオプションがあります。私は例としてquaternion タイプを使用しますが、これは行列などにも等しく適用できます。また、 私は具体的にEigenのタイプを公開することについて話していますが、この 質問は、使用中の他の外部ライブラリにも同様に適用できます。

1)基本的なタイプ経由でデータを渡すために、クライアントが必要となるだけで、基本的なC++のタイプ

このオプションを使用します。 例えば、クォータニオン(4つの要素)に渡すため、一方が行うことができ:

void my_func(double my_quat[4]) 

2)固有の型を公開

固有の配列及び四元のためのいくつかのテンプレートの種類を提供します。

void my_func(const Eigen::Quaterniond& my_quat) 

3)クライアント

のための様々なタイプの単純なラッパーを作成します:関数は四元が必要な場合 たとえば、私は、(本当に Quaternion<double>のtypedefである)固有の Quaterniond タイプを使用することができます

は、私は私のAPIに パスへ クライアントが(おそらくファクトリ関数のいくつかの並べ替えを経由して)を作成しなければならないことを非常に単純な四元タイプ(たとえば、単純な構造体のいくつかの並べ替え)を作成することができます。

void my_func(const quaternion_t& my_quat) 

私のライブラリはquaternion_tのタイプを内部のEigen の表現に変換します。

私は、APIのタイプが であるという強い感覚が欲しいので、オプション1があまりにも好きではありません。オプション2では、 ではなく、 という異なるバージョンのEigenを使用すると、クライアントにEigenも使用する必要があります( の場合、ヘッダーのみのライブラリです)。それはオプション3を残します。

人々はどう思いますか?私は基本的に自分の質問に答えましたか?そこに何かの例がありますか?

関連の質問

関連する質問はhereを頼まれましたが、本当に1 外部のタイプを公開する必要があるかどうかの詳細には触れませんでした。

+0

オプション3は、オプション1と2の両方を使用するコンストラクタとは何ですか? C++のセマンティクスでは、これを動作させるために宣言型を十分に転送することができます(Eigenを持たないクライアントはヘッダーをインクルードでき、コンパイル時には失敗しません)。 – Lalaland

+0

私はそのようなことについて考えていましたが、typedefされたテンプレート型を宣言する方法についてはあまりあいまいですが、私の場合はクライアントが型の具体的なインスタンスを渡すように制限しています'Quaternion 'とは対照的に 'Quaternion 'のように)。 – plasma

+0

クライアントがコンストラクタを使用してEigen型からライブラリ型を作成していて、若干実装が変更されている可能性のある別のバージョンのEigenを使用している場合に、何が起こるかについては少し曖昧です。 – plasma

答えて

2

ラップ/カプセル化。実装の変更として、四元数のノルムのような計算結果をキャッシュするなど、いくつかの追加機能を追加したいとします。クライアントコードで呼び出しを変更せずにサードパーティのタイプを公開すると、(簡単に)それを行うことはできません。

+0

私は同意します。しかし、必ずしもマトリックス/クォータニオン/等全体を公開する必要はありません。私のライブラリの機能はより高いレベルにあるので、私自身のライブラリを使用してください。ラッパークラスがAPIと通信するための最小限の機能を提供し、クライアントがそれらのタイプに関連付けられたデータを実際に操作するために必要なものを使用できるようにすることは意味がありますか? – plasma

+0

薄いラッパーはOKです。 my_quaternion :: foo(){それらの戻り値を返す.quaternion.foo(); }は、公開する関数にとっては問題ありません。 @Attilaが最も劇的なケースの上に指摘したように、あなたはライブラリを切り替えることができます。クライアントが扱うべきではない面倒です。 固有値から本格的な数学オブジェクトへのアクセスが重視されていると感じたら:getEigen()変換関数と固有値を入力として受け取るctorも提供します。あなたが別のライブラリに再実装したとしても。 – djechlin

+0

ctorまたはgetEigen()関数を使用するクライアントと私のライブラリが異なるバージョンのEigenでコンパイルされるとどうなりますか?両方のバージョンがABIと互換性があるとすれば、私たちは良いと思います。しかし何かが変わるべきであれば、これはもはや働かないだろうか?特に、私はDSOとして私のライブラリを提供するケースを考えていますが、私はクライアントに静的ライブラリを与えても何が起こるのか分かりません。 – plasma

2

短期間で第三者の図書館を公開するのが最も簡単ですが、長期的に見るとあなたの背中を悩ませる可能性が非常に高いです。最も簡単なのは、型がそこにあるので、自分で思いつく必要はありません。将来別の実装ライブラリを使用したい場合、またはクライアントがあなたに渡すデータの拡張を許可したい場合は、あなたを噛んでしまいます。

基本的なタイプのみを使用することは、あなた自身のものとほとんど同じですが、正当な理由がないため、はるかに低いレベルです。あなたのユーザは、何が何であるかに関するドキュメントを絶えず参照することなく、あなたのライブラリを使用するのに苦労するでしょう。

柔軟性が必要な場合は、独自のタイプを使用することをおすすめします。既存の型をすべて再作成する必要があるため、多くの作業が面倒に見えるかもしれませんが、ライブラリのインターフェイスで多少異なる型を使用すると、実装が容易になります後でもっと良く変わる。

答えは本当にあなたの目標と長期的な計画/予測に依存します。現在の実装から自分自身を変更することがない場合は、既存のタイプを再利用することができますが、将来計画変更を行う場合は、独自の独立したインターフェースを作成する必要があります。

関連する問題