6

SFINAE を使用してグローバル演算子をチェックすることから情報を収集します<<? およびテンプレート、 decltype および non-classtypes、次のコードを取得しました。

http://ideone.com/sEQc87

基本的に、両方の質問のコードを組み合わせて、宣言printがある場合は関数を呼び出し、そうでない場合はメソッドを呼び出します。ostreamto_string

質問 1 から取得

namespace has_insertion_operator_impl {
  typedef char no;
  typedef char yes[2];

  struct any_t {
    template<typename T> any_t( T const& );
  };

  no operator<<( std::ostream const&, any_t const& );

  yes& test( std::ostream& );
  no test( no );

  template<typename T>
  struct has_insertion_operator {
    static std::ostream &s;
    static T const &t;
    static bool const value = sizeof( test(s << t) ) == sizeof( yes );
  };
}

template<typename T>
struct has_insertion_operator :
  has_insertion_operator_impl::has_insertion_operator<T> {
};

質問 2 から取得

template <typename T>
typename std::enable_if<has_insertion_operator<T>::value, T>::type
print(T obj) {
    std::cout << "from print()" << std::endl;
}

template <typename T>
typename std::enable_if<!has_insertion_operator<T>::value, T>::type
print(T obj) {
    std::cout << obj.to_string() << std::endl;
}

次に、私のクラスは次のようになります。

struct Foo
{
public:
    friend std::ostream& operator<<(std::ostream & os, Foo const& foo);
};

struct Bar
{
public:
    std::string to_string() const
    {
        return "from to_string()";
    }
};

そしてテスト出力:

int main()
{
    print<Foo>(Foo());
    print<Bar>(Bar());

    //print<Bar>(Foo()); doesn't compile
    //print<Foo>(Bar()); doesn't compile

    print(Foo());
    print(Bar());

    print(42);
    print('a');
    //print(std::string("Hi")); seg-fault
    //print("Hey");
    //print({1, 2, 3}); doesn't compile
    return 0;
}

print(std::string("Hi"));ラインセグフォルト。誰でも理由を教えてもらえますか?

4

1 に答える 1