I was trying to make a simplified version of my code for this question. In the process I encountered something that does not make sense to me. Can someone explain why I obtain the following result? Here is the code, it should compile and run in gcc.
#include <string>
#include <iostream>
#include <typeinfo>
using std::string;
template <typename T> inline char getType(const T&) {return 'S'; }
inline char getType(const char&) {return 'C';}
template <typename T> inline char getType(T*) {return 'A'; }
template <typename T> inline void writeData(const T& x) {
printf("Calling default writeData...\n");
char type = getType(x);
if (type == 'S') {
printf("ERROR: binaryWrite::writeData -> Structure not defined.\n");
exit(1);
}
std::cout << x << std::endl;
}
template <typename T> inline void writeData(T* x, const unsigned int& len) {
printf("Writing array with writeData...\n");
char type = getType(x[0]);
std::cout << len << std::endl;
if (type == 'S') {
for (int i=0; i < len; ++i) {
writeData(x[i]);
}
} else {
for (int i=0; i < len; ++i) {
std::cout << x[i] << std::endl;
}
}
}
class binaryWrite {
public:
binaryWrite(void) {}
template <typename T>
void write(const T& x, const char* name) {
writeData(x);
}
};
inline void writeData(const string& s) {
unsigned int len = s.size();
const char* pt = s.c_str();
writeData(pt, len);
}
int main () {
string str = "Hello World";
writeData(str);
binaryWrite BF;
BF.write(str, "str");
return 0;
}
This is the output:
manuel-lopezs-macbook-pro:binaryFiles jmlopez$ g++ -o example example.cpp
manuel-lopezs-macbook-pro:binaryFiles jmlopez$ ./example
Writing array with writeData...
11
H
e
l
l
o
W
o
r
l
d
Calling default writeData...
ERROR: binaryWrite::writeData -> Structure not defined.
First it calls writeData with the string version. After I try calling that version with the binaryWrite function write (This function calls writeData) it calls the function defined by the template.
I played around with it and found out that if I move the overloaded function for the string right above the class definition of binaryWrite then I get the result that I want.
This is the change:
inline void writeData(const string& s) {
unsigned int len = s.size();
const char* pt = s.c_str();
writeData(pt, len);
}
class binaryWrite {
public:
binaryWrite(void) {}
template <typename T>
void write(const T& x, const char* name) {
writeData(x);
}
};
This is the output
Writing array with writeData...
11
H
e
l
l
o
W
o
r
l
d
Writing array with writeData...
11
H
e
l
l
o
W
o
r
l
d
It would seem as if binaryWrite did not know about the overloaded function writeData for string in the first case. But after the switch, since I defined the overloaded function first then it knows. Is this the right explanation?
What I would like to do eventually is use the macro WRITESTRUCT for other types but this definition would be in some other files so I won’t be able to write them before the definition of binaryWrite. Any ideas how to overcome this problem if my explanation is indeed the right one?
Okay, playing around with your code, I found it also performs correctly if you move ALL of the
writeDatatemplates and overload below thebinaryWriteclass definition.When the compiler encounters
binaryWrite::write, it checks to see if it has a definition forwriteDataat that point. It’s selectingtemplate <typename T> inline void writeData(const T& x)at that point because it only has access to the first two templates. It then never goes back to see if there is a better choice.When you move the writeData templates after binaryWrite, the compiler has no definition for writeData, and decides it will look again during template instantiation. So when you then use
binaryWrite::write, it picks the direct overload, instead of the template.