1

Possible Duplicate:
Why can templates only be implemented in the header file?

I wrote a template function and the call of type int in function main:

template <class T> T max (T a, T b) {    }
int main() {
    max(1,2);
}

As most of the C++ books said, the int max(int,int) function will be generated during the compile time when the compiler meet the max(1,2).

But in another file, I wrote the declaration of the int max(int,int) and call it, but the compiler(actually the linker) caught an error said the reference of max(int,int) is not found.

extern int max(int,int);
max(1,2);    // Error:undefined reference to max(int,int)

So , what's the wrong point, and how can I call the max(int,int) function using extern and not a header file declaration.

Many thanks.

Community
  • 1
  • 1
lichenbo
  • 1,019
  • 11
  • 13

3 Answers3

2

This question is only answered a few thousand times. The short form is: You either have to arrange for the template definition to be visible when used such that the compiler can implicitly instantiated the function template or you have to explicitly instantiate the function template.

Note, that the declaration extern int max(int, int); declares a non-template function max() taking two int as parameter. This reference will never be satisfied by a function template, whether it is instantiated or not.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • also the extern keyword basically means "this function it's defined in another file and you shouldn't care about that at compile time" – user1824407 Dec 27 '12 at 12:05
  • If the question has been asked before, why not close it as a duplicate? – Sergey Kalinichenko Dec 27 '12 at 12:05
  • I'm sorry, but when I search the keywords 'template' 'extern' 'function' via google, what I found is only the extern template feature in C++0x, and no one actually solved my problem. I won't search the 'only in header file' when I met with the problem and describe that in an undirect way. – lichenbo Dec 27 '12 at 12:15
1

The extern int max(int,int); declares a non-template function. It wouldn't match the template, even if that had been visible in your other file.

The correct way is to put the template in a header, and include that everywhere the function is used (or, even better, use the max template already available in the standard library).

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
0

When you declare extern int max(int, int) you tell the compiler that there's a function with this signature defined somewhere, not necessarily in the same translation unit. extern is actually redundant, as functions have external linkage by default.

Now, you seem to think that this declaration provides a definition for an instantiation of the template function with T = int. It does not, the two are not related in any way. Plain functions are prefered over function templates when the compiler searches for a candidate for the call max(1,2). When it finds the declaration int max(int, int), it's a perfect match and its job is done - it never even tries to instantiate the template. After compilation is done, the linker is supposed to find the definition, and as you haven't provided it, you get an undefined reference.

So you can either write a definition

int max(int, int) { }

or explicitly tell the compiler to use a template

max<int>(1,2);

You can also specialize the template for int type

template<>
int max<int>(int, int) { };

but note that if you keep the normal function, it would still be a better match.

jrok
  • 54,456
  • 9
  • 109
  • 141