一图胜千言:
#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;
}
编译器在将数字0传递给接受字符串的方括号运算符时不会发出警告。相反,这会编译,并在进入该方法之前失败,显示以下信息:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
供参考:
> 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)
我的猜测
编译器在进入该方法时隐式使用了std::string(0)
构造函数,这没有任何好处,却导致了相同的问题(搜索上面的错误信息)。
问题
有没有办法在类的一侧修复这个问题,使API用户不会感到这个问题,并且可以在编译时检测到错误?
也就是说,添加一个重载函数。
void operator[](size_t t) {
throw std::runtime_error("don't");
}
不是一个好的解决方案。
operator[]()
,接受一个整型参数,并且不定义它。 - Peter