Vaut mille mots:
#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;
}
Le compilateur ne se plaint pas en passant le numéro 0 à l'opérateur de parenthèse acceptant une chaîne. Au lieu de cela, cela compile et échoue avant l'entrée dans la méthode avec:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Pour référence:
> 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)
Ma conjecture
Le compilateur utilise implicitement le std::string(0)
constructeur pour entrer la méthode, ce qui génère le même problème (google l'erreur ci-dessus) sans raison valable.
Question
Existe-t-il un moyen de résoudre ce problème côté classe, afin que l'utilisateur de l'API ne le ressente pas et que l'erreur soit détectée au moment de la compilation?
Autrement dit, ajouter une surcharge
void operator[](size_t t) {
throw std::runtime_error("don't");
}
n'est pas une bonne solution.
operator[]()
qui accepte un int
argument et ne le définissez pas.