c++visual-c++implicit-conversionmove-constructormove-assignment-operator

msvc /permissive- std::string overloaded operator '=' is ambiguous


It compiles with /permissive but fails with /permissive-. What is not conforming and how to fix it?

Why it's fine in (2) but fails in (4)(3)? If I remove operator long it also fine.

How to fix it without changing call site (3,4)?

#include <string>
struct my
{
    std::string myVal;
    my(std::string val): myVal(val) {}

    operator std::string() { return myVal; };
    operator long() { return std::stol(myVal); };
};
int main()
{
    struct MyStruct
    {
        long n = my("1223"); // (1)
        std::string s = my("ascas"); // (2)
    } str;
    str.s = my("ascas"); // (3)
    str.n = my("1223"); // (4)
}

error message

error C2593: 'operator =' is ambiguous
xstring(2667): note: could be 'std::basic_string<...> &std::basic_string<...>::operator =(const _Elem)'
        with
        [
            _Elem=char
        ]
xstring(2648): note: or 'std::basic_string<...> &std::basic_string<...>::operator =(const std::basic_string<...> &)'
xstring(2453): note: or 'std::basic_string<...> &std::basic_string<...>::operator =(std::basic_string<...> &&) noexcept(<expr>)'
Source1.cpp(17): note: while trying to match the argument list '(std::string, my)'

Solution

  • Vlad from Moscow answer have a nice explanation. But there was no solution. Here it is using SFINAE

    template<typename T = long, typename = std::enable_if_t<
        std::is_same_v<T, long> || std::is_same_v<T, int>>>
    operator T() const
    {
        return l();
    }
    
    operator std::string() const
    {
        return s();
    }