代码之家  ›  专栏  ›  技术社区  ›  JVApen

当const ref和value存在时,为什么转换运算符会导致不明确的重载

  •  2
  • JVApen  · 技术社区  · 7 年前

    我在看一个包装类,基于 https://www.fluentcpp.com/category/strong-types/ 主要的区别是我正在替换 get() 方法使用显式强制转换运算符,因为这会在使用代码检查时触发问题。

    正如您在下面的简化代码中所看到的,我有3个casting操作符重载:

    • const A & int
    • 从…起 A && int
    • 从…起 康斯特A& const int &

    写作时: static_cast<int>(a) ,我预计会有超负荷的工作 康斯特A& int int 康斯特国际酒店; 为什么会这样?

    与此类似,它似乎允许 const int &r = static_cast<const int &>(createA()); 我认为这是一个终生的错误。(假设createA返回A by值)


    编译器资源管理器中的简化代码: https://gcc.godbolt.org/z/YMH9Ed

    #include <utility>
    
    struct A
    {
        int v = 42;
        explicit operator int() const & { return v; } // Removing this line works
        explicit operator int() && { return std::move(v); }
        explicit operator const int &() const & { return v; }
    };
    
    int main(int, char**)
    {
        A a;
        int r = static_cast<int>(a);
        return r;
    }
    

    编译错误:

    <source>:14:13: error: ambiguous conversion for static_cast from 'A' to 'int'
        int r = static_cast<int>(a);
                ^~~~~~~~~~~~~~~~~~~
    <source>:6:14: note: candidate function
        explicit operator int() const & { return v; }
                 ^
    <source>:8:14: note: candidate function
        explicit operator const int &() const & { return v; }
                 ^
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   NathanOliver    7 年前
    explicit operator int() const & { return v; }
    

    explicit operator const int &() const & { return v; }
    

    都是同样好的转换。 a 是左值,因此可以调用这两个函数。 const 因此,这两个函数都必须对 A. int const int& 从…起

    您需要去掉其中一个转换运算符,或者删除常量 从…起

    显式运算符常量int&()土木工程;{返回v;}
    

    变成

    explicit operator const int &() & { return v; }
    

    所以非常量左值给你一个常量引用。