Вопрос

noob here. The following is a fragment from a class definition I came accross in a book example:

double& operator[](int i);
double operator[](int i) const;

My question is: why is this not ambiguous? When compiling the files of the project, the compiler doesn't give any error. Also, in the following (imagine AnyClass contains a valarray<double> object for example and I want to access it directly):

AnyClass test;
cout << test[2]

which version does the compiler use?

Это было полезно?

Решение

It's not ambiguous because the const is part of the signature and can be used for overload resolution. So if you use operator[] on a non-const object, it picks the overload without const because that's the most specific one. And if you use it on a const object, it picks the overload with const because that's the only one that applies.

Другие советы

If called on a const object, the const version will be used, else the other one.

That's how the compiler resolves the ambiguity.

AnyClass test;
const AnyClass const_test;
std::cout << test[2];       // calls operator[](int)
std::cout << const_test[2]; // calls operator[](int) const

To understand this, you mostly simply need to realize that a const on an argument is enough to disambiguate a call:

#include <iostream>

void foo(char* ptr)
{
    std::cout << "mutable: " << ptr << std::endl;
}

void foo(const char* ptr)
{
    std::cout << "const: " << ptr << std::endl;
}

int main()
{
    const char* constHello = "hello";
    char mutableHello[] = "hello";
    foo(constHello);
    foo(mutableHello);
}

This prints:

const: hello
mutable:hello

The compiler will choose the least restrictive overload it can. So if you use a char* when there's a char* overload, it's the one it will pick; but if there isn't any, the compiler will decide that casting it to a const char* is a viable conversion (the converse is, obviously, not true).

Now, the very simple thing is that all methods pass a this pointer as the first parameter of any function. This parameter is hidden for the sake of simplicity. The const at the end of the method qualifies the this argument. Since, as we've just seen, a const on a pointer is enough to disambiguate overloads, this will effectively work.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top