クラス用の単純なテキストフォーマッタを実装しています。その中のmain関数は、連結される値のリストを受け取ることができます。または、オプションで、パラメータがostreamのフレンズでない場合は、他のすべてのパラメータをstd :: stringに変換する最初のパラメータとして変換関数を受け入れます。C++のVariadicテンプレートで、呼び出し可能な型と呼び出し不可能な型を選択するための洗練されたソリューションがありますか?
次のコードはアイデアを示していますが、コンパイルされません。わかりやすくするために、この例ではcoutに出力します。
struct formater{
template<typename P, typename... PS>
void format(const P& p, const PS&... ps){
if (std::is_convertible<P, std::function<void()>>::value){
cout << p(ps...) << endl;
} else {
cout << p;
log(ps...);
}
}
};
コードがコンパイルされない理由は、Pが呼び出し可能であるならば、それは「他」ブランチでcoutに出力することができません、あり、そしてPは呼び出し可能でない場合、それはPを教えてくれますです呼び出し可能でなく、 "then"ブランチのps ...パラメータを受け取ることができません。
私はenable_ifを使用すると考えましたが、条件の両方のケース(TとF)を定義しているので、同じ関数の再定義を得てコンパイルも失敗します。
私はstatic_ifを模倣しようとする可能性がありますが、それは全くエレガントに見えません。
Pが呼び出し可能でSFINAEであることを確認するうまい方法があるのだろうかと思います。たぶん、P、(PS ...) - > std :: stringのパラメータ型を知っていることを利用しているかもしれません。
は' P'ことになっていますか? – cdhowie
'PARAM'が' const PS&... 'で呼び出し可能かどうか、あるいは 'PARAM'がまったく呼び出せるかどうか(つまり関数ポインタか関数オブジェクトか)を知りたいですか? –
この特定のシナリオでは、最初のオプションが好きです。とにかく、私は確かに第二のものについて不思議です。 – dvicino