Vale más que mil palabras:
#include<string>
#include<iostream>
class SayWhat {
public:
SayWhat& operator[](const std::string& s) {
std::cout<<"here\n"; // To make sure we fail on function entry
std::cout<<s<<"\n";
return *this;
}
};
int main() {
SayWhat ohNo;
// ohNo[1]; // Does not compile. Logic prevails.
ohNo[0]; // you didn't! this compiles.
return 0;
}
El compilador no se queja al pasar el número 0 al operador de soporte que acepta una cadena. En cambio, esto se compila y falla antes de ingresar al método con:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Para referencia:
> g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test && ./test
> g++ --version
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
Mi conjetura
El compilador está usando implícitamente el std::string(0)
constructor para ingresar el método, lo que genera el mismo problema (google el error anterior) sin ninguna buena razón.
Pregunta
¿Hay alguna forma de arreglar esto en el lado de la clase, para que el usuario de la API no sienta esto y el error se detecte en el momento de la compilación?
Es decir, agregar una sobrecarga
void operator[](size_t t) {
throw std::runtime_error("don't");
}
No es una buena solución.
operator[]()
que acepte un int
argumento y no lo defina.