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

标签 c++ type-conversion c++17

我正在寻找一个基于 https://www.fluentcpp.com/category/strong-types/ 的包装类主要区别是我替换了 get()具有显式转换运算符的方法,因为这会在使用时在代码审查期间引发问题。

正如您在下面的简化代码中看到的,我有 3 个强制转换运算符重载:

  • 来自 const A &int
  • 来自 A &&int
  • 来自 const A &const int &

写入时:static_cast<int>(a) ,我预计 const A & 的过载至int要使用的。然而,它似乎有利于intconst int &过载同等。 为什么要这样做?

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


编译器资源管理器中的简化代码: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; }
             ^

最佳答案

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

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

同样具有良好的转化效果。 a 是左值,因此可以调用这两个函数。 a 也不是 const,因此两个函数都必须对 a 应用 const 转换,因此它们仍然同样好。剩下的就是“返回类型”,intconst int&,但是它们都同样可以用来创建int

您需要删除其中一个转换运算符,或者删除常量 来自

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

把它变成

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

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

关于c++ - 当 const-ref 和 value 存在时,为什么转换运算符会导致不明确的重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54161013/

相关文章:

go - 用它的变量制作一个结构的 slice

database - Oracle 中是否有任何隐式日期格式转换?

java - 线程池的设计模式

c++ - 在 C 代码中使用用 C++ 编写的函数

c++ - CMake Visual Studio 找不到库

arrays - 如何将包装为字符串的向量转换为 Pandas 数据帧中的 numpy 数组?

java - 当我从 native Java 方法抛出 C++ 异常时会发生什么?

c++ - c++ 中是否有任何日期时间模块

c++ - std::is_invocable 为假,但 std::invoke 有效

c++ - 为什么这个引用绑定(bind)格式错误?