隐式转换运算符不会在运算符重载时启动

Implicit conversion operator doesn't kick in with operator overloading

本文关键字:运算符 重载 启动 转换      更新时间:2023-10-16

请考虑以下示例:

#include <string>
#include <sstream>
struct Location {
    unsigned line;
    template<typename CharT, typename Traits>
    operator std::basic_string<CharT, Traits>() const {
        std::basic_ostringstream<CharT, Traits> ss;
        ss << line;
        return ss.str();
    }
};
int main() 
{
    using namespace std::string_literals;
    Location loc{42};
    std::string s1 = "Line: "s.append(loc) + "n"s; // fine
    //std::string s2 = "Line: "s + loc + "n"s; // error
}

注释行导致编译错误:no match for 'operator+' 。为什么?我最初的想法是,它将首先使用 operator std::string 进行转换,然后执行对operator+的调用,就像它对.append所做的那样。

它只是隐式转换的一个级别,所以应该执行并考虑它,不是吗?

现场演示

您的运算符是模板化的,因此需要推导模板参数。你不能这样做,因为编译器试图将basic_string<_CharT, _Traits, _Alloc>与你的Location匹配,但它失败了。

所以问题在于重载,而不是转换,因为代码实际上从未达到这一点。

更改此设置:

std::string s2 = "Line: "s + loc + "n"s;

对此:

std::string s2 = "Line: "s + std::string(loc) + "n"s;

你应该没问题,因为如果你仔细观察编译器错误,它会提到:

template argument deduction/substitution failed:
prog.cc:22:32: note:   'Location' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>'
   std::string s2 = "Line: "s + loc + "n"s; // error
                                ^~~

和其他类似消息。

显式

强制转换为 std::string 对我有用:https://godbolt.org/g/WZG78z

    std::string s2 = "Line: "s + std::string(loc) + "n"; // was error