メタプログラミング: 関数のオーバーロードに基づくテンプレートの選択
C メタプログラミングでは、型プロパティに基づいて条件付きでテンプレート関数を定義するのが一般的な手法です。ただし、場合によっては、特定の関数が存在しないことに基づいてテンプレートが選択されるという、逆のシナリオを定義するのが難しい場合があります。
具体的には、提供されている例では、目標はテンプレートを定義することです。 2 つの実装の間で選択する関数 stringify:
後者の条件を表現しようとするときに問題が発生します。次の失敗した試みは、ネストされたenable_if テンプレートを使用して to_string が定義されていないことを確認しようとします:
template<typename T> enable_if_t<!decltype(to_string(T{})::value, string> (T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
この問題を解決するには、Walter Brown の void_t 型特性を利用できます:
template <typename...> using void_t = void;<p>これを使用すると、次のように has_to_string 特性を定義できます:</p> <pre class="brush:php;toolbar:false">template<typename T, typename = void> struct has_to_string : std::false_type { }; template<typename T> struct has_to_string<T, void_t<decltype(std::to_string(std::declval<T>()))> > : std::true_type { };
これで、has_to_string 特性に基づいた条件付きテンプレートの特殊化を使用して stringify テンプレートを定義できます:
template<typename T> enable_if_t<has_to_string<T>::value, string> stringify(T t){ return std::to_string(t); } template<typename T> enable_if_t<!has_to_string<T>::value, string> stringify(T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
この解決策std::to_string が指定された型に対して定義されているかどうかに基づいて、stringify の適切な実装を効果的に選択します。
以上がC メタプログラミングで関数の不在に基づいてテンプレート選択を実装するにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。