Reputation: 57
I'm trying to write a function that implements a general behavior for all types that are not enums, a general behavior for all types that are enums, and then being able to specialize a specific behavior for some types by fully specializing the function. Here is my code so far:
// Func.h
#include <cstdio>
#include <type_traits>
template <typename T, std::enable_if_t<!std::is_enum<T>{}>* = nullptr >
void Func()
{
printf("General case\n");
}
template <typename T, std::enable_if_t<std::is_enum<T>{}>* = nullptr >
void Func()
{
printf("enum\n");
}
template <>
void Func<bool>()
{
printf("bool\n");
}
// main.cpp
#include <Func.h>
enum Enum
{
A,
B
};
int main()
{
Func<float>();
Func<Enum>();
Func<bool>();
}
It does not compile and I don't really know how to get that right. If i let the specialized prototype as in the code above, I get this linking error:
error LNK2005: "void __cdecl Func<bool,0>(void)" (??$Func@_N$0A@@@YAXXZ) already defined in main.obj
and if I make the specialized prototype template<> void Func<bool, nullptr>()
, I get this compilation error:
error C2912: explicit specialization 'void Func<bool,nullptr>(void)' is not a specialization of a function template
These tests are done using Visual Studio 2015 compiler with c++14 standard
I don't know where to go from here, any help would be greatly appreciated
Upvotes: 1
Views: 57
Reputation: 26282
You get a linking error because Func<bool>()
is defined in a header file that is included into multiple compilation units. Solution is simple: put inline
before void Func<bool>()
:
template<>
inline void Func<bool>()
{
// ...
}
Function templates are implicitly inline
, but functions and explicit template specializations are not. If they are defined in a header file, they should be marked as inline
.
Upvotes: 2