Templates, function overloading and their order of appearence
<p>I was trying to make a simplified version of my code for <a href="http://stackoverflow.com/questions/7179062/how-to-let-c-know-that-an-operator-has-been-overloaded-for-a-class">this question</a>. 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.</p>

<pre><code>#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;typeinfo&gt;

using std::string;

template &lt;typename T&gt; inline char getType(const T&amp;) {return 'S'; }
inline char getType(const char&amp;) {return 'C';}
template &lt;typename T&gt; inline char getType(T*) {return 'A'; }

template &lt;typename T&gt; inline void writeData(const T&amp; x) { 
    printf("Calling default writeData...\n");
    char type = getType(x);
    if (type == 'S') {
        printf("ERROR: binaryWrite::writeData -&gt;  Structure not defined.\n");
        exit(1);
    }
    std::cout &lt;&lt; x &lt;&lt; std::endl;
}

template &lt;typename T&gt; inline void writeData(T* x, const unsigned int&amp; len) { 
    printf("Writing array with writeData...\n");
    char type = getType(x[0]);
    std::cout &lt;&lt; len &lt;&lt; std::endl;
    if (type == 'S') {
        for (int i=0; i &lt; len; ++i) {
            writeData(x[i]);
        }
    } else {
        for (int i=0; i &lt; len; ++i) {
            std::cout &lt;&lt; x[i] &lt;&lt; std::endl;
        }
    }   
}

class binaryWrite {
public:
    binaryWrite(void) {}
    template &lt;typename T&gt; 
    void write(const T&amp; x, const char* name) { 
        writeData(x);
    }
};

inline void writeData(const string&amp; 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;
}
</code></pre>

<p>This is the output:</p>

<pre><code>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 -&gt;  Structure not defined.
</code></pre>

<p>First it calls <code>writeData</code> with the string version. After I try calling that version with the <code>binaryWrite</code> function <code>write</code> (This function calls <code>writeData</code>) it calls the function defined by the template.</p>

<p>I played around with it and found out that if I move the overloaded function for the string right above the class definition of <code>binaryWrite</code> then I get the result that I want.</p>

<p>This is the change:</p>

<pre><code>inline void writeData(const string&amp; s) {
    unsigned int len = s.size();
    const char* pt = s.c_str();
    writeData(pt, len);
}

class binaryWrite {
public:
    binaryWrite(void) {}
    template &lt;typename T&gt; 
    void write(const T&amp; x, const char* name) { 
        writeData(x);
    }
};
</code></pre>

<p>This is the output</p>

<pre><code>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
</code></pre>

<p>It would seem as if <code>binaryWrite</code> did not know about the overloaded function <code>writeData</code> for <code>string</code> in the first case. But after the switch, since I defined the overloaded function first then it knows. Is this the right explanation? </p>

<p>What I would like to do eventually is use the macro <code>WRITESTRUCT</code> 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 <code>binaryWrite</code>. Any ideas how to overcome this problem if my explanation is indeed the right one?</p>
