This question has been partially answered: the solution is that in one of my class's fields, specifically _escape, has UB. However, it is still unknown why Visual Studio's stack trace does not display the operator<< function nor does the debugger find it - almost as if there was an optimization(I disabled optimizations) to remove the symbol and merge it with the print function.
What I already know
I have seen all the popular posts on SO about << operator overload. I have followed all the basic semantics. This isn't a duplicate question of any of the popular posts.
To override the << operator, one needs to define a function with the general format of:
ostream& operator<<(ostream& os, const MyObject& dt)
I have done so in my program,
I'm using Microsoft Visual Studio 2015 for this project, and using the debugger to try to step into the << operator function. However, it never gets inside of the function that I defined as follows:
std::ostream& operator <<(std::ostream& os, const EscapeStr& t)
{
t.print(os);
return os;
}
where EscapeStr is a class I defined with the following function definition for 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];
}
}
The problem
I see the print() function being called here using the VS debugger, but I cannot observe the program entering the scope of my overridden <<, but rather it's going into the std definition of <<, with the following signature:
template<class _Traits> inline
basic_ostream<char, _Traits>& operator<<(
basic_ostream<char, _Traits>& _Ostr,
const char *_Val); // insert NTBS into char stream
This is extremely weird, because only the ostream override operator has access to my public function currently. Is Visual Studio just lying?
I don't understand what's going on, as one of my other overloads do work, and the signature isn't even exact(without the const and reference):
/// ostream operator for indent
std::ostream& operator <<(std::ostream &os, indent x)
{
static const std::string spaces(" ");
while(x.d--) {
os << spaces;
}
return os;
}
As a result, my program is exhibiting some UB(reading the std library code would drive me insane). Here's an ideone to show the UB: https://ideone.com/jxro5s . Any help would be greatly appreciated.
Extra information for MVCE and clarity
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];
}
}
};
Here is an image of the stack trace - no sign of the << operator.
EDIT: To predict future comments/posts about me not using std::quoted - I'm trying to make the program compatible with versions less than C++11.