這個問題已得到部分回答:解決方法是在我的課程的一個領域,特別是_escape,有UB。但是,Visual Studio的堆棧跟蹤爲什麼不顯示運算符函數,調試器是否也能找到它 - 這幾乎就像是有一種優化(我禁用了優化)來移除符號並將其與打印函數合併在一起。覆蓋<<(stream)運算符時,調試會轉換爲std的<< impl而不是?
我已經知道
我看到所有的熱門帖子上SO約< <運算符重載。我遵循了所有的基本語義。這不是任何熱門帖子的重複問題。
要覆蓋< <操作,需要定義一個函數的一般格式爲:我已經在我的程序這樣做
ostream& operator<<(ostream& os, const MyObject& dt)
,
我使用Microsoft Visual Studio 2015年對於這個項目,並使用調試器嘗試進入運算符功能< <。但是,從來沒有,我定義爲函數內得到如下:
std::ostream& operator <<(std::ostream& os, const EscapeStr& t)
{
t.print(os);
return os;
}
其中EscapeStr是我用下面的函數定義定義print
類:
void print(std::ostream& os) const {
for (int i = 0; i < _elem.length(); i++) {
char c = _elem[i];
if (_delim[c]) {
for (int j = 0; j < _escLen; j++) {
os << _escape[j];
}
}
os << _elem[i];
}
}
問題
我看到使用VS調試器在這裏調用了print()函數,但我無法觀察到進入我重寫的範圍的程序,而是進入的std定義<,具有以下特徵:
template<class _Traits> inline
basic_ostream<char, _Traits>& operator<<(
basic_ostream<char, _Traits>& _Ostr,
const char *_Val); // insert NTBS into char stream
這是非常奇怪的,因爲只有ostream的覆蓋運營商可以訪問我目前公共職能。 Visual Studio只是在說謊嗎?
我不明白這是怎麼回事,我的其他重載之一,做的工作,並且簽名甚至不是準確(不常量和參考):
/// ostream operator for indent
std::ostream& operator <<(std::ostream &os, indent x)
{
static const std::string spaces(" ");
while(x.d--) {
os << spaces;
}
return os;
}
結果,我程序正在展示一些UB(閱讀std庫代碼會讓我瘋狂)。這是一個顯示UB的人:https://ideone.com/jxro5s。任何幫助將不勝感激。
爲MVCE和清晰度
const static char _delims[] = { '\\', '"' };
const static std::vector<char> delims(_delims, _delims + 2);
class EscapeStr {
const static unsigned short MAX_CHAR = 256;
std::string &_elem;
bool _delim[MAX_CHAR];
const char* _escape;
int _escLen;
public:
EscapeStr(std::string &elem,
const std::vector<char> &delim = std::vector<char>(1, '"'),
const std::string &escape = "\\") :
_elem(elem),
_escape(escape.c_str()),
_escLen(escape.size())
{
for (int i = 0; i < MAX_CHAR; i++) {
_delim[i] = false;
}
for (int i = 0; i < delim.size(); i++) {
_delim[delim[i]] = true;
}
}
void print(std::ostream& os) const {
for (int i = 0; i < _elem.length(); i++) {
char c = _elem[i];
if (_delim[c]) {
for (int j = 0; j < _escLen; j++) {
os << _escape[j];
}
}
os << _elem[i];
}
}
};
這裏的額外信息是堆棧跟蹤的圖像 - 沒有< <運營商的標誌。
編輯:爲了預測未來的評論/關於我不使用std :: quoted的帖子 - 我試圖讓程序與低於C++ 11的版本兼容。
如果調用'print()',那麼你的覆蓋的'operator <<'被調用嗎?另外,你的'operator <<'應該聲明爲'const'。 – ArchbishopOfBanterbury
看起來你的類有一個cast操作符,它被調用來將'EscapeStr'轉換爲'char const *'。這很可能是你的'operaro <<'函數在你調用它的時候沒有聲明。 –
@ArchbishopOfBanterbury我會這麼想,但是我在該運算符的每一行上都放了斷點,並且它從未插入。 – OneRaynyDay