模板,函数重载及其顺序 [英] Templates, function overloading and their order of appearence

查看:114
本文介绍了模板,函数重载及其顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为我的代码做一个简化版本这个问题。在这个过程中,我遇到了一些对我没有意义的东西。有人可以解释为什么我获得以下结果?这里是代码,它应该编译并运行在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆