Этот вопрос частично ответил: решение заключается в том, что в одном из полей моего класса, в частности _escape, есть UB. Однако до сих пор неизвестно, почему в трассировке стека Visual Studio не отображается оператор < <, и отладчик не находит его - почти как если бы была оптимизация (отключена оптимизация), чтобы удалить символ и объединить его с функцией печати.При переопределении оператора << (поток) отладка переходит в 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 класс I определяется следующим определением функции для 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];
}
}
Проблема
Я вижу функцию print(), вызываемую здесь, используя отладчик VS, но я не могу наблюдать, как программа вводит область моего переопределенного < <, но скорее она входит в определение 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];
}
}
};
Вот изображение трассировки стека - никаких признаков оператора < <.
EDIT: Предсказывать будущие комментарии/сообщения обо мне, не используя std :: quoted - Я пытаюсь сделать программу совместимой с версиями менее C++ 11.
Если вызывается 'print()', то, безусловно, вы вызываете ваш переопределенный 'operator <<'? Кроме того, ваш 'operator <<' должен быть объявлен 'const'. – ArchbishopOfBanterbury
Похоже, у вашего класса есть оператор литья, который вызывается для преобразования 'EscapeStr' в' char const * '. Скорее всего, ваша функция 'operaro <<' не объявляется в то время, когда вы ее вызываете. –
@ArchbishopOfBanterbury Я тоже так думаю, но я поставил точки останова на каждую строку этой перегрузки оператора и никогда не входил. – OneRaynyDay