模板,函数重载及其顺序 [英] Templates, function overloading and their order of appearence
问题描述
我试图为我的代码做一个简化版本这个问题。在这个过程中,我遇到了一些对我没有意义的东西。有人可以解释为什么我获得以下结果?这里是代码,它应该编译并运行在gcc。
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;
}
这是输出:
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.
首先用字符串version调用 writeData
。在我尝试使用 binaryWrite
函数写
调用该版本(此函数调用 writeData
)它调用模板定义的函数。
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.
我玩了一下,发现如果我移动的重载函数的字符串 binaryWrite
的类定义然后我得到我想要的结果。
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.
这是更改:
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
b $ b
似乎 binaryWrite
不知道重载的函数 writeData
for string
在第一种情况。但是在切换之后,因为我首先定义了重载函数,那么它知道。这是正确的解释吗?
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?
我想要做的最终是使用宏 WRITESTRUCT
用于其他类型,但这个定义会在一些其他文件,所以我将无法在定义 binaryWrite
之前写它们。任何想法如果我的解释确实是正确的,如何克服这个问题?
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?
推荐答案
如果你移动所有 writeData
模板并且重载在 binaryWrite
类定义下面,它也会正确执行。
Okay, playing around with your code, I found it also performs correctly if you move ALL of the writeData
templates and overload below the binaryWrite
class definition.
当编译器遇到 binaryWrite :: write
时,它会检查是否有 writeData
。它选择 template< typename T> inline void writeData(const T& x)
,因为它只能访问前两个模板。
When the compiler encounters binaryWrite::write
, it checks to see if it has a definition for writeData
at that point. It's selecting template <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.
当在binaryWrite之后移动writeData模板时,编译器没有为writeData定义,并决定它将在模板实例化期间再次查找。所以当你使用 binaryWrite :: write
,它选择直接重载,而不是模板。
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.
这篇关于模板,函数重载及其顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!