msvc / permissive- std :: string重载运算符'='不明确

Own*_*gic 8 c++ visual-c++ implicit-conversion move-constructor move-assignment-operator

与一起编译,/permissive但与一起失败/permissive-。什么不符合以及如何解决?

为什么很好,(2)但失败了?如果我删除它也很好。(4)(3)operator long

如何在不更改呼叫站点的情况下进行修复(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)
}
Run Code Online (Sandbox Code Playgroud)

错误信息

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)'
Run Code Online (Sandbox Code Playgroud)

son*_*yao 6

我想您是说(2)没问题,但(3)失败

注意#2是初始化,它调用; 的构造函数std::string。#3是赋值,它调用的赋值运算符std::string。他们是不同的东西。

分配运算符的调用是模棱两可的,因为的赋值运算符std::string具有重载char,可以从中进行隐式转换long(这是标准转换),然后导致歧义(std::string如编译器所抱怨的那样,赋值运算符为)。这两个隐式转换序列都包含一个用户定义的转换(从mystd::stringlong),它们在onverload分辨率上的排名相同。

调用构造函数是可以的,因为它没有这样的重载(采用char)。


Own*_*gic 0

来自莫斯科的弗拉德回答有一个很好的解释。但没有解决办法。这里使用的是 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();
}
Run Code Online (Sandbox Code Playgroud)