あなたの前提は少しロードされています。テンプレートの古い構文 (関数、クラス、変数、またはエイリアス テンプレートのすべて) を概念の導入によって変換することは可能ですが、多くの場合、それは人為的であり、バトンを渡します。std::transform
例として従来の関数テンプレートを取り上げます。
// current
template<typename In, typename Out, typename Func>
Out transform(In first, In last, Out out, Func func);
代わりに、非常に明白な方法で概念の紹介を使用するように変換できます。
TransformParameters{In, Out, Func}
Out transform(In first, In last, Out out, Func func);
おわかりのように、これはかなり機械的なものであり、無意味でもあります。TransformParameters
疑似概念が他の場所で再利用できる可能性はどのくらいで、それがプログラマーにどのように役立つのでしょうか? この宣言は、古いものよりも新しい情報を提供しません。この疑似概念が正しく記述されていると仮定すると、プログラマーは改善された診断/過負荷解決の恩恵を受けるはずです。
代わりに、賢明で概念を有効にした の宣言がそのように見えることを期待std::transform
します (標準的な概念がまだないため、ここでは架空の概念と特性を使用しているため、原則に焦点を当てています)。
template<Iterator In, Iterator Out, Value Func>
requires
Callable<Func, iterator_reference_t<In>>
&& AssignableFrom<
iterator_reference_t<Out>,
result_of_t<Func(iterator_reference_t<In>)>
>
Out transform(In first, In last, Out out, Func func);
std::transform
要件であるという考えは、関連付けられた式を持つという事実を反映しています*out = func(*in)
。さらに、requires-clauses に表示される要素は確かに再利用可能です (反復子参照型でありstd::result_of_t
、実際に既に使用されています)。
この比較的単純な例は、概念の導入がどこでも機能しない理由を示しています。一部の require 要素には、私がサードパーティの型と呼びたいもの、つまりiterator_reference_t<…>
andresult_of_t<…>
が含まれますが、一部の入力型は一度に複数の関係に関与します (たとえば、 andIt
に表示されます)。Iterator
Callable
それ以外の場合、つまり、すべての引数の型とそれらの型のみの間にちょうど 1 つの関係があり、その関係が意図を合理的に表現しており、できれば再利用可能である場合。次に、概念の導入が適切な場所になる可能性があります。(ただし、概念の紹介を伴う簡略化されたテンプレートは、この適用分野をもう少し広げます。)