我试图为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
时,它将选择直接重载而不是模板。