Worth a thousand words:
#include<string>
#include<iostream>
class SayWhat {
public:
SayWhat& operator[](const std::string& s) {
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;
}
The compiler is not complaining when passing the number 0 to the bracket operator accepting a string. Instead, this compiles and fails before entry to the method with:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
For reference:
> 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)
My guess
The compiler is implicitly using the std::string(0)
constructor to enter the method, which yields the same problem (google the above error) for no good reason.
Question
Is there anyway to fix this on the class side, so the API user does not feel this and the error is detected at compile time?
That is, adding an overload
void operator[](size_t t) {
throw std::runtime_error("don't");
}
is not a good solution.
operator[]()
that accepts anint
argument, and don't define it. – JabanNULL
->std::string
conversion) over on the Software Engineering Stack Exchange: Compile-time checking for NULL initialized std::string – Esmeralda