I've got a compilation warning. It runs well but just a warning. Could someone please tell me why and what it is?...Thank.
CODE:
class A {
public:
A & operator[](const std::string & a) {
std::cout << "string" << std::endl;
return (*this);
}
const A & operator[](int a) const {
std::cout << "int" << std::endl;
return (*this);
}
};
int main() {
A a;
a["g"][3]; // OK here without using index 0
a[0]; // WARNING here if index is 0
return (0);
}
WARNING:
tmp.cc: In function ‘int main()’:
tmp.cc:21:8: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
a[0];
^
tmp.cc:12:15: note: candidate 1: const A& A::operator[](int) const
const A & operator[](int a) const {
^
tmp.cc:7:9: note: candidate 2: A& A::operator[](const string&)
A & operator[](const std::string & a) {
1. For overload resolution of calls to member functions, the arguments to the function are treated as if there is an extra argument (the implied argument forming the this pointer)
(Note that in this case, one of the member functions is const-qualified)
2. The literal 0 could be either the int zero or the nullptr
The error is reproduced in this snippet
(with simpler code, with explicit pointer arguments instead of an implicit this pointer)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <string>
struct A ;
void foo( A*, std::string ) ;
void foo( const A*, int ) ;
int main()
{
A* pa = nullptr ;
// Error: ambiguous call to overloaded function
// void foo( A*, std::string ) : foo( pa, 0 )
// arg 1: exact match (A*), arg 2: conversion (nullptr to string)
// void foo( const A*, int ) : foo( pa, 0 )
// arg1: conversion (pointer conversion A* to const A*). arg 2: exact match (int)
foo( pa, 0 ) ;
}
@JLBorges, Thanks for your clarifying. But I am still confused of the solution, is it possible to implement such requirement with overloading operator []?
It looks ugly the API user has to do a explicit conversion 'a[int(0)]'...
It looks ugly the API user has to do a explicit conversion 'a[int(0)]'...
The problem can be solved for the user at the cost of some library complexity.
The standard contains a special case that allows literal integers with the value zero to convert to pointers of any type. Some indirection solves the problem:
> is it possible to implement such requirement with overloading operator []?
¿what requirement?
¿why is the string version non-const? it's quite different behaviour for the same named operation.