我试图为this question简化代码。在此过程中,我遇到了一些对我来说毫无意义的事情。有人可以解释为什么我得到以下结果吗?这是代码,它应该在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;
}

这是输出:
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.

首先,它使用字符串版本调用writeData。在尝试使用binaryWrite函数write(此函数称为writeData)调用该版本后,它将调用模板定义的函数。

我试用了它,发现如果将字符串的重载函数移到binaryWrite类定义的正上方,那么我会得到想要的结果。

这是更改:
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);
    }
};

这是输出
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

在第一种情况下,似乎binaryWrite不了解writeData的重载函数string。但是在切换之后,由于我首先定义了重载函数,因此它知道了。这是正确的解释吗?

我最终想做的是将WRITESTRUCT宏用于其他类型,但是此定义将存在于其他文件中,因此我将无法在binaryWrite定义之前编写它们。如果我的解释确实正确,有什么想法可以解决这个问题?

最佳答案

好的,在处理您的代码时,我发现如果将所有writeData模板移到binaryWrite类定义下方并重载,它也可以正确执行。

当编译器遇到binaryWrite::write时,它将检查该点是否具有writeData的定义。此时选择template <typename T> inline void writeData(const T& x)是因为它只能访问前两个模板。然后,它再也不会回头看看是否有更好的选择。

当您在binaryWrite之后移动writeData模板时,编译器没有为writeData定义,并决定在模板实例化时将再次查找。因此,当您随后使用binaryWrite::write时,它将选择直接重载而不是模板。

09-27 12:20