0
// hello.h
template<typename T>
bool comp( T first, T second )
{
    return first < second;
}

// hello.cpp
template bool comp(int, int); // would ONLY allow comp to access int

// main.cpp
std::cout << std::boolalpha << comp(10, 12) << std::endl;    // fine
std::cout << std::boolalpha << comp(2.2, 3.3) << std::endl;  // fine why!

Question 1> It seems that I cannot put the implementation code for comp in hello.cpp. Is that true?

Question 2> I try to limit the input parameters of comp to integer ONLY. why the second line in the main.cpp still compiles?

Thank you

q0987
  • 34,938
  • 69
  • 242
  • 387
  • 1
    1. http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file. 2. Standard conversions. – chris May 15 '13 at 18:31
  • You want to restrict template to certain types, here is the post: http://stackoverflow.com/questions/874298/c-templates-that-accept-only-certain-types – gongzhitaao May 15 '13 at 18:37
  • The solution I posted in the question works for class. For example, I am able to implement class Stack that only supports int/double but not char etc. However, I found the same solution doesn't work with function template. – q0987 May 15 '13 at 18:39

2 Answers2

1

It seems that I cannot put the implementation code for comp in hello.cpp. Is that true?

Usually, yes; most templates need to be defined in every translation unit in which they're used, so they usually need to be defined in a header.

However, it looks like you're trying to explicitly instantiate it for one (or some set of) types, while disallowing it for others. In that case, you need to declare it in the header:

// hello.h
template<typename T>
bool comp( T first, T second );

define and instantiate it in a source file:

// hello.cpp
template<typename T>
bool comp( T first, T second )
{
    return first < second;
}

template bool comp(int, int);

and use the instantiated specialisations in any file that includes the header:

// main.cpp
std::cout << std::boolalpha << comp(10, 12) << std::endl;    // fine
// std::cout << std::boolalpha << comp(2.2, 3.3) << std::endl;  // link error

why the second line in the main.cpp still compiles?

In your example, the template definition is still available (in the header) to implicitly instantiate any specialisations needed. So the second line instantiates it for double and compiles happily. Moving the template definition into a separate source file prevents that.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • The lesson I learned today is 1> we have to put template implementation code in CPP in order to achieve pre-determined set for a function template. 2> we have to put template implementation code in H if we don't have such a requirement. – q0987 May 15 '13 at 19:36
0

This will implement comp so C++'s parameter conversions (like your double to int) will not happen.

// hello.h
template<typename T>
bool comp( T first, T second );

// hello.cpp
template<>
bool comp( int first, int second )
{
    return first < second;
}

This leaves the general form of comp without a definition. Only the specific int implementation will exist.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • This is not what I expected solution. I simplified my example code in order to post the question here. In the real case, the function is allowed to accept ClassA, ClassB, and ClassC but not others. I don't want to add the function implementation for each class. – q0987 May 15 '13 at 18:35
  • @q0987 Perhaps you simplified the question too much. Consider editing your question so it mentions what you're looking for. – Drew Dormann May 15 '13 at 18:43