简体   繁体   中英

Unresolved externals with explicit template instantiations. What is the declaration syntax?

Here's some simplified code to demonstrate the problem I have.

I have a template function for which I only wish to compile certain fixed instantiations.

The function declarations are:

// *** template.h ***
int square (int x);
double square (double x);

The definitions are:

// *** template.cpp ***
#include "template.h"

// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
    return x*x;
}

// explicit instantiations
template int square (int x);
template float square (float x);

And, an example use is:

// *** main.cpp ***

#include <iostream>
using namespace std;

#include "template.h"

int main (void)
{
    cout << square(2) << endl;
    cout << square(2.5) << endl;
}

An attempt to compile this results in a link errors, roughly:

main.obj : unresolved external symbol "int square(int)" referenced in function main

I understand what the problem is: the function signatures of my explicit template instantiations do not match those in the header file.

What is the syntax for the (forward) declaration of the explicit template instantiations please? I do not wish to forward declare the template definition, or to move the template definition into a header file.

For what it's worth, I do have a workaround, which is to use wrapper functions, adding the following to the above files:

// *** template.cpp ***

// ...

// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }

That compiles and works as expected. However, this seems like a hack to me. There should be something more elegant than this available in C++ and template syntax.

Any help or hints would be much appreciated.

You need to declare the function template in your header:

template <typename T>
T square(T x);

As you have it now, you declare two nontemplate functions in the header, which are never defined.

There is no other way if you want to hide the template from the header file. You have to have wrapper functions because int square (int x); does not have the same name mangling as template int square (int x); and C++ does not offer you a way to change that.

You can check out how name mingling differs in Visual Studio as an example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM