Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separate declaration and definition of specialization of template function : different behaviour for member and nonmember functions

I want to declare specialization for function template, but define it later in source file. Consider next example:

.hpp

// approach #1
template <typename T> const char *GetTypeName();
template <> const char *GetTypeName<int>();

// approach #2
template <typename T> class TypeName {static const char *Get();};
template <> const char *TypeName<int>::Get();

.cpp

// approach #1
template <> const char *GetTypeName<int>()
{
    return "int"
}

// approach #2
template <> const char *TypeName<int>::Get()
{
    return "int"
}

In MSVC 2012 (CTP is not installed), both variants compile fine, but nonmember variant (#1) raises linker errors (unresolved externals, blah). Is it normal behaviour? MSVC specific? Compiler bug? Fixed in CTP?

EDIT
I am using specialized versions only. They are declared in headers and defined in sources. This approach works for members, but does not works for standalone functions.

EDIT 2
Hmm... I'm trying to build same snapshot at home (identical MSVC installation, no CTP), and it links without issues. Seems like local bug or corrupted installation.

like image 766
Shadows In Rain Avatar asked Oct 28 '25 08:10

Shadows In Rain


1 Answers

A function template is not a function. A fully specialized function template is a function.

Since all (odr-used) functions must be defined, you must have a way to generate definitions for arbitrary template instantiations. Thus the definition of the primary function template must be in the header.

header.h:

template <typename T>            //  this
const char * GetTypeName()       //  is
{                                //  not
    return "foo";                //  a
}                                //  function

template <>
const char * GetTypeName<int>();

impl.cpp:

#include "header.h"

template <>
const char * GetTypeName<int>()
{
    return "int";
}
like image 132
Kerrek SB Avatar answered Oct 30 '25 00:10

Kerrek SB