6

これは機能し、 1 を印刷します

#include <iostream>

struct Int {
    int i;
    operator int() const noexcept {return i;}
};

int main() {
    Int i;
    i.i = 1;
    std::cout << i;
}

ただし、これは GCC 4.8.1 でのコンパイルに失敗します

#include <iostream>
#include <string>

struct String {
    std::string s;
    operator std::string() const {return s;}
};

int main() {
    String s;
    s.s = "hi";
    std::cout << s;
}

エラーの関連部分は次のとおりです。

エラー: 'operator<<' に一致しません (オペランドの型は 'std::ostream {aka std::basic_ostream}' と 'String' です)
std::cout << s;

をちょきちょきと切る

template std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<<(basic_ostream<_CharT , _Traits>& __os,

/usr/include/c++/4.8/bits/basic_string.h:2753:5: 注: テンプレート引数の推論/置換に失敗しました:
main.cpp:25:18: 注: 「文字列」は「const std::」から派生したものではありませんbasic_string<_CharT, _Traits, _Alloc>'<br> std::cout << s;

同じテンプレート引数を持つstd::coutとのみを使用します。std::stringのように暗黙的な変換を取得できない理由が本当にわかりませんIntintでは機能するのに、では機能しないのはなぜstd::stringですか?

4

2 に答える 2

2

<< 演算子には、std::string 以外の型のオーバーロードのプールがあるようです。clang++ コンパイラーを使用して見たように。

コンパイラは String から std::string への暗黙的な変換を行いますが、定義された << 演算子のいずれとも一致しません。

std::string に << 演算子を定義すると機能します

#include <iostream>
#include <string>

std::ostream& operator<<(std::ostream& s, const std::string& str)
{
        s << str.c_str();
        return s;
}

struct String {
    std::string s;
    operator std::string() const {return s;}
};

int main() {
    String s;
    s.s = "hi";
    std::cout <<  s;
}

同じ問題の詳細については、http: //forums.codeguru.com/showthread.php ?432227-RESOLVED-Implicit-conversion-to-std-string をご覧ください。

ある投稿に見られるように。

問題は operator<< ここにテンプレートがあり、ユーザー定義の変換が暗黙的なインスタンス化のテンプレートの引数推定でおそらく考慮されていないため、型 TestClass に対してテンプレートのインスタンス化を作成できないことです (少なくともセクション 14.7.7 で見つけることができませんでした。 1 (暗黙的なインスタンス化). これにより、呼び出し "std::cout << obj << '\n';" に対して空のオーバーロード セットが発生し、したがってエラーが発生します. インスタンス化が既に発生したかどうかは問題ではありません. テンプレート候補は完全に一致するオーバーロード セットに選択されます (配列からポインターへの減衰と const 修飾を除く - http://groups.google.co.in/group/com...29910b6?hl=en& )。

明示的なオーバーロード operator<< を std::string 型で提供すると、それは非テンプレートであり、オーバーロード セットに加算されるため、オーバーロードの解決/呼び出し可能な一致を実行中に暗黙的な変換が呼び出されます。

于 2013-07-09T04:11:12.940 に答える