式によるSFINAE
C++11時代からある話題だが...。置き換え失敗はエラーにあらずで有名なSFINAEを、式によってコントロールする手法。
例えば、二つの引数を差し込む事のできる関数を定義するとする。しかし、渡したいのはイテレータか生ポインタのみであり、それ以外の値を受け付けないようにしたいというな仕様の場合。
using namespace std::string_literals; template<class _Iterator> constexpr auto f(const _Iterator&,const _Iterator&)->decltype(typename _Iterator::iterator_category(),std::string()) { return "iterator"s; } template<class Pointer> constexpr auto f(const Pointer*,const Pointer*)->std::string { return "pointer"s; }
関数シグネチャの一部に、ある特定のタイプでなければ有効でない式を記述する。そしてoperator,を用いてその式が有効である時に限り次の式へ処理が行くよう定義している。
SrookCpplibrariesのmake_elements_stringにもこの機能を用いている。
以下のように書ける。
#include<srook/string/make_elements_string.hpp> #include<iostream> #include<vector> int main() { std::vector<int> v{1,2,3,4,5}; const int ar[]{4,5,6,7,8}; std::cout<<srook::make_elements_string(std::begin(v),std::end(v))<<std::endl; std::cout<<srook::make_elements_string(std::begin(ar),std::end(ar))<<std::endl; std::cout<<srook::make_elements_string(1,2)<<std::endl; }