允许隐式强制转换运算符仅用于常量引用

Det*_*roc 6 c++

有没有办法使自定义强制转换运算符仅在对象为 const 时可用(或仅隐式)?

例子:

class Foo;
class Bar;

class MyClass {
    public:
        operator Foo() const;
        operator Foo() = delete; // this doesn't seem to have any effect
        // I also tried explicit operator Foo(); - no change
        operator Bar();
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,如果它是 const,我希望MyClass隐式转换为const,但如果它不是 const,则隐式转换为。这是因为存在一对重载函数:FooBar

void f(Foo x);
void f(Bar x);
Run Code Online (Sandbox Code Playgroud)

我希望能够传递MyClassto f,以便根据它是否为 const 选择正确的函数。然而,通过这种方式,我得到了对重载函数的模糊调用。为什么?

int main() {
    f(MyClass());
}
Run Code Online (Sandbox Code Playgroud)

重要提示:我知道可以通过将强制转换运算符转换为构造函数来轻松完成这项工作,但不幸的是,FooBar、 和f无法修改。对于上下文,这是解决我的其他问题的一个想法:有没有办法解决这种不明确的隐式强制转换运算符重载?

Die*_*ühl 2

在检查其访问和/或删除之前,选择最佳可行的重载。由于原始类定义没有最佳可行的重载,因此它甚至没有达到该阶段。也就是说,需要解决重载决策的歧义。

使用两个转换运算符之一explicit确实可以解决问题(测试程序仍然存在由于Bar不完整而导致的错误)。explicit使用(和ed,尽管这是可选的)转换的组合= delete确实会产生一个可能是所寻找的版本:

#include <iostream>
class Foo {};
class Bar {};

class MyClass {
    public:
        explicit operator Foo() const& = delete;
        explicit operator Foo() && = delete;
        operator Foo()& { return Foo(); }

        explicit operator Bar() const& = delete;
        operator Bar() && { return Bar(); }
        explicit operator Bar() & = delete;;
};

void f(Foo) { std::cout << "f(Foo)\n"; }
void f(Bar) { std::cout << "f(Bar)\n"; }

int main() {
    f(MyClass());
    MyClass x;
    f(x);
}
Run Code Online (Sandbox Code Playgroud)

我没有设法创建一个也接受的版本MyClass const y; f(y);:使const&转换运算符非显式(对于任一转换)会在其他地方导致歧义。