デフォルトのパラメーター値を必要とするテンプレート関数の推奨される設計は何ですか?

StackOverflow https://stackoverflow.com/questions/1551539

質問

私は現在、関数テンプレートでいっぱいの API のクリーンアップに取り組んでおり、次のコードを書きたいという強い欲求がありました。

template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

このテンプレートを呼び出すときは、次のようにしたいと思います。

std::string text("hello");
doWork(100, 20.0, &text);
doWork('a', text);         // oops!
doWork<char, std::string, void>('a', text);  // to verbose!

残念ながら、コンパイラはオプションのパラメータの型を推測できないため、2 番目の呼び出しはコンパイルされません。私はパラメータの型が何であるかは実際には気にせず、むしろその値が NULL であることを気にしているので、これは残念です。また、3 回目の呼び出しのルートは読みやすさを妨げるため避けたいと考えています。

これにより、テンプレート引数を作成しようとしました V にはデフォルトの型がありますが、関数テンプレートの引数にデフォルトの型を適用できないため、これも機能しません (少なくとも VC++ 9.0 を使用している場合)。

template <typename T, typename U, typename V = void>  // oops!
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

残された唯一の選択肢は、オーバーロードを導入することです。 doWork テンプレート引数について何も知りません V.

template <typename T, typename U>
void doWork(const T& arg1, const U& arg2)
{
    doWork(arg1, arg2, 0);
}

template <typename T, typename U, typename V>
void doWork(const T& arg1, const U& arg2, V* optionalArg);

これはこの問題を解決する最善のアプローチでしょうか?私が感じる唯一の欠点は、関数テンプレートに適切なデフォルトを持つ多くのパラメーターが含まれている場合、多くの簡単な転送関数が導入される可能性があることです。

役に立ちましたか?

解決

私はあなたのソリューションでは、明示的にテンプレートパラメータを指定する必要はありませんが、あなたの転送機能は、完璧なソリューションであると思いますか? (0は任意V*タイプにcovertedできる整数定数である。)またdoWorddoWork

一般的なルールとして、彼らは非常に強力なペイオフを持っていないオプションのパラメータを回避しよう。

これはは、あなたのクライアントを強制する方が簡単かもしれない2つのパラメータとテンプレートの3つのパラメータバージョンの両方をサポートするために多くの余分な機構に追加appriopriate比べた場合だけ, (void*)0を追加するために機能します。これは、しかし、期待される用途に依存します。

他のヒント

それは第三のパラメータを持っていない場合は、

ビューのクライアントコードの観点から、なぜそれがものを発明する必要があるのでしょうか?

あなたは使いやすさと読みやすさを目指すのであれば、

、私はあなたのラッパー・メソッドに同意する:それは完璧な理にかなっている、とのあなたのが書いたラッパーは、三番目のパラメータののまともな値を担当していますの必要としました。

必要に応じて

その上で、それは、異なる専門分野ごとに異なるデフォルトを使用することが可能となる。

1 つの可能性は、オプションの引数が最初になるようにテンプレート引数を並べ替えることです。

template <typename V, typename T, typename U>
void doWork(const T& arg1, const U& arg2, V* optionalArg = 0);

doWork<void>('a', text); 

転送もOKのようです。

ただし、デフォルトの引数とテンプレートはうまく一致していないようです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top