This question requires a fairly lengthy setup, but carry me.
Consider the following files:
Type1.hpp
#ifndef TYPE1_HPP
#define TYPE1_HPP
struct Type1
{
int a;
int b;
};
#endif
Type2.hpp
#ifndef TYPE2_HPP
#define TYPE2_HPP
struct Type2
{
int c;
int d;
};
#endif
MyTemplate.hpp
#ifndef MYTEMPLATE_HPP
#define MYTEMPLATE_HPP
template <typename T>
struct MyTemplate
{
T t;
};
#endif
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
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;
}
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;
}
When compiling with Clang:
clang++-3.6 -o testover -std=c++11 -Wall main.cpp Functions.cpp
leads to a compilation error:
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.
When the middle name of the function in Functions.hpp and cpp changes to func2, the code compiles.
My question is: why do compilers require different information here with overloaded functions compared to two functions with different names?
source
share