q0987
q0987

Reputation: 35982

How to add a predetermined set of template instantiation into function template

// 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

Upvotes: 0

Views: 110

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254501

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.

Upvotes: 1

Drew Dormann
Drew Dormann

Reputation: 63795

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.

Upvotes: 0

Related Questions