为什么所有模板实例化都需要完整才能解决函数重载?

khu*_*tun 5 c++

这个问题需要很长的设置,但请忍受。

考虑以下文件:

Type1.hpp

#ifndef TYPE1_HPP
#define TYPE1_HPP

struct Type1
{
    int a;
    int b;
};

#endif
Run Code Online (Sandbox Code Playgroud)

Type2.hpp

#ifndef TYPE2_HPP
#define TYPE2_HPP

struct Type2
{
    int c;
    int d;
};

#endif
Run Code Online (Sandbox Code Playgroud)

MyTemplate.hpp

#ifndef MYTEMPLATE_HPP
#define MYTEMPLATE_HPP

template <typename T>
struct MyTemplate
{
    T t;
};

#endif
Run Code Online (Sandbox Code Playgroud)

Functions.hpp

#ifndef FUNCTIONS_HPP
#define FUNCTIONS_HPP

struct Type1;
struct Type2;
template <typename T> struct MyTemplate;

int func(const MyTemplate<Type1>& param);
int func(const MyTemplate<Type2>& param);

#endif
Run Code Online (Sandbox Code Playgroud)

Functions.cpp

#include "Functions.hpp"
#include "MyTemplate.hpp"
#include "Type1.hpp"
#include "Type2.hpp"

int func(const MyTemplate<Type1>& param)
{
    return param.t.a + param.t.b;
}

int func(const MyTemplate<Type2>& param)
{
    return param.t.c - param.t.d;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp

#include "Functions.hpp"
#include "MyTemplate.hpp"
#include "Type1.hpp"
#include <iostream>

int main()
{
    MyTemplate<Type1> x;
    x.t.a = 1;
    x.t.b = 2;

    int y = func(x);

    std::cout << y << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

使用Clang编译时:

clang++-3.6 -o testover -std=c++11 -Wall main.cpp Functions.cpp
Run Code Online (Sandbox Code Playgroud)

导致编译错误:

In file included from main.cpp:2:
./MyTemplate.hpp:7:7: error: field has incomplete type 'Type2'
    T t;
      ^
main.cpp:12:18: note: in instantiation of template class 'MyTemplate<Type2>' requested here
    int y = func(x);
             ^
./Functions.hpp:5:8: note: forward declaration of 'Type2'
struct Type2;
       ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

当Functions.hpp和cpp中第二个函数的名称更改为时func2,代码将编译。

我的问题是:为什么与带有不同名称的两个函数相比,这里的重载函数为什么编译器需要不同的信息?