私はhas_ostream_operator<T>
SFINAEテストを定義して、指定されたタイプを取り除くことができるかどうかを確認しようとしています。私はそれを働かせているが、私の定義がhas_ostream_operator
の場合にのみ、埋め込み演算子ではなくメソッドとしてoperator<<
を呼び出す。換言すれば、この作品:SFINAEがvoid_tで動作するためのメソッドとしてoperator <<を呼び出さなければならないのはなぜですか?
decltype(std::declval<std::ostream>().operator<<(std::declval<T>()))>
これしない:以下
decltype(std::declval<std::ostream>() << std::declval<T>())>
テストケース(またhttp://coliru.stacked-crooked.com/a/d257d9d6e0f3f6d9で見ることができます)。 void_tの定義は、私がC++ 14でしか使っていないので、含まれています。あなたは
std::declval<std::ostream&>() << std::declval<T>()
// ^
std::declval<std::ostream>()
が右辺値である必要
#include <iostream>
namespace std {
template<class...>
using void_t = void;
}
template<class, class = std::void_t<>>
struct has_ostream_operator : std::false_type {};
template<class T>
struct has_ostream_operator<
T,
std::void_t<
decltype(
std::declval<std::ostream>().operator<<(std::declval<T>()))>>
: std::true_type {};
struct Foo {};
template<class X>
void print(
const X& x,
std::enable_if_t<has_ostream_operator<X>::value>* = 0)
{
std::cout << x;
}
template<class X>
void print(
const X&,
std::enable_if_t<!has_ostream_operator<X>::value>* = 0)
{
std::cout << "(no ostream operator<< implementation)";
}
int main()
{
print(3); // works fine
print(Foo()); // this errors when using infix operator version
return 0;
}
'void_t'のその定義は未定義の動作を誘導する([namespace.std]/1)。 – Columbo
これ以外のコンパイル時エラーをランタイムエラーに変換するには、このすべての問題を解決してもよろしいですか?私は実際の使用事例について非常に興味があります。あなたの目標は実際には 'x 'の' print(x) 'を書くことができ、' x'が印刷可能でないことが判明したときにランタイムメッセージを表示させることですか? – JorenHeit