1
class Test {
public:
    operator string() {
        return string{"TEST!"};
    }
};

int main() {
    cout << Test{};
}

Test オブジェクトが暗黙的に文字列に変換されて出力されることを期待していましたが、エラーが発生します。

error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

この明示的な変換は機能します:

cout << string{Test{}};

にキャストすることで機能しましたconst char*

class Test {
public:
    operator const char*() {
        return "TEST!";
    }
};

次に出力します。

cout << Test{}; //Yay it works.

はすでに からへcout << stringの暗黙的な変換であると想定しています。文字列へのキャストを使用すると、 から への 2 レベルの変換は実行されません。に直接キャストした後、動作します。(前提が間違っていたら訂正してください)stringchar *Test to string to char *const char*


仮定が正しいことを証明するには

class Test {
public:
    operator string() {
        return string{"TEST!"};
    }
};

ostream& operator<< (ostream& os, string s){
    os << s;
    return os;
}

これにより、文字列から直接型推定が実行され、Test to string文字列が出力されます。私が試した後、それはうまくいきます!

cout << Test{}; //YAY WORKS! OUTPUT "TEST!"

について特別なことcout << stringが説明されていBorgleaderます。仮定は部分的に正しく、部分的に間違っています。

4

2 に答える 2

4

キーワードは、のexplicitように自分で明示的に変換する必要があることを意味しますstd::string(Test{})。暗黙的な変換を無効にします。

cout << string{Test{}}; // <-- this is explicit, you've got implicit and explicit confused

ルールは、テンプレート引数の推論中に、ユーザー定義の変換が試行されないことです。ただし、指摘したように、int への変換演算子しかない場合はコンパイルされます。これは、そのオーバーロードが関数テンプレートではないためです。参照ページを見ると、次のことがわかります。

basic_ostream& operator<<( int value );

これはテンプレート化されていないオーバーロードであるため、コンパイラはユーザー定義の変換を探します。

于 2013-08-09T18:55:41.997 に答える