1

我知道 C++ 中没有基于返回类型的合法重载;即你不能做类似的事情:

int operator ++ getOwner();
char operator ++ getOwner();

但是,我偶然发现了以下内容:

https://stackoverflow.com/a/9569120/1376317

class Proxy
{
    My const* myOwner;
public:
    Proxy( My const* owner ) : myOwner( owner ) {}
    operator int() const
    {
        return myOwner->getInt();
    }
    operator char() const
    {
        return myOwner->getChar();
    }
};

我的问题是运算符重载如何在此配置中工作。你如何在你的 main.cpp 中调用它来获得这种重载。编译器如何推导,如何调用正确的重载?

4

6 回答 6

3

我的问题是运算符重载如何在此配置中工作。

这些运算符提供隐式转换。这意味着这个类可以在许多需要intorchar的上下文中使用,并将使用这些运算符来提供预期值。

你如何在你的 main.cpp 中调用它来获得这种重载。

以下是一些隐式转换的示例:

Proxy p = whatever();
int i = p;   // convert to int
char c = p;  // convert to char
long l = p;  // ERROR: ambiguous

void f(int);
f(p);        // convert to int

void g(int);
void g(char);
g(p);        // ERROR: ambiguous

您还可以使用通常的转换符号请求显式转换:

long l = static_cast<int>(p);  // convert to int, then to long
g((char)p);                    // convert to char

编译器如何推导,如何调用正确的重载?

每当出现类型不匹配时,编译器都会查找转换序列。规则相当复杂,但基本上该序列最多可以包括一个用户定义的转换(使用像这样的运算符或转换构造),以及标准转换,例如intto long

于 2013-09-04T15:50:51.047 回答
2

这有时被称为返回类型解析器习语或“返回类型重载”。由于需要隐式转换的使用上下文(例如,基于要初始化或分配的对象的类型),选择要调用的转换运算符。例如:

#include <stdio.h>

class RtR {
public:
    operator int() const
    {
        puts("operator int()");
        return 42;
    }
    operator double() const
    {
        puts("operator double()");
        return 3.14;
    }
};

void f(int) {}

int main()
{
    RtR x;
    int i = x; // or int i = RtR();
    double d = x;
    f(x);
}

输出:

operator int()
operator double()
operator int()

现场观看

于 2013-09-04T15:51:36.410 回答
1

在 13.1 可重载声明中:

仅返回类型不同的函数声明不能​​被重载。[注意:...它不适用于由于名称查找(例如,由于使用指令)或重载决议(例如,对于运算符函数)而制造的函数集...]

因此这是有效的:

struct X {
    // Conversion function:
    operator int () { return 1; }
    operator double () { return 2; }
};

另外(与问题没有直接关系):

struct Y
{
    // Operator (Function call):
    int operator () (int) { return 1; }
    double operator () (double) { return 2; }

    // Operator (Subscripting):
    int operator [] (int) { return 1; }
    double operator [] (double) { return 2; }

    // Operator (Shift):
    int operator << (int) { return 1; }
    double operator << (double) { return 2; }

    // and more ...
};
于 2013-09-04T16:54:55.263 回答
0

上面的代码用于operator类型转换,并提供了一种将类型转换为 and 的隐Proxyint方法char

于 2013-09-04T15:46:49.770 回答
0

编译器根据转换调用的上下文“知道”,例如:

Proxy p;

// p_int will be set equal to p.my_owner->getInt()
int p_int = p;

// p_char will be set equal to p.my_owner->getChar()
char p_char = p;
于 2013-09-04T15:48:07.633 回答
0

它是代理的事实无关紧要。同样的事情适用于任何课程。这些是转换运算符,编译器根据调用代码中的使用方式选择正确的版本。

struct S {
    operator int() const { return 1; }
    operator double() const { return 2.0; }
};

int main() {
    S s;
    int i = s;
    double d = s;
    std::cout << i << ' ' << d << '\n';
    return 0;
}
于 2013-09-04T15:48:25.050 回答