/* test.cpp
Only the declaration is visible -> needs to link against correct instantiation.
*/
#include <iostream>
#include "test.h"
int main() {
std::cout << Type{}.get<Enum::Member1>() << '\n';
std::cout << Type{}.get<Enum::Member2>() << '\n';
std::cout << Type{}.get<Enum::Member3>() << '\n';
}
/* test.h
Contains the function-template-declaration, not the implementation.
*/
enum class Enum
{
Member1,
Member2,
Member3
};
struct Type
{
template <Enum Value>
int get() const;
};
/* test.tpp
.tpp extension indicates that it contains template implementations.
*/
#include "test.h"
template <Enum Value>
int Type::get() const
{
return static_cast<int>(Value); // silly implementation
}
// instantiate.cpp
#include "test.tpp"
#include<array>
template <Enum Value>
struct Instantiate
{
using Function = int (Type::*)() const;
static constexpr Function f1 = &Type::get<Value>;
// many more member-functions
};
// Version 2: working
/*template class Instantiate<Enum::Member1>;
template class Instantiate<Enum::Member2>;
template class Instantiate<Enum::Member3>;*/
// Version 3: not working
/*template <Enum ... Pack>
struct InstantiateAll:
Instantiate<Pack> ...
{};
template class InstantiateAll<Enum::Member1, Enum::Member2, Enum::Member3>;*/
// Version 3: working
template <Enum ... Pack>
struct InstantiateAll
{
using Function = int (Type::*)() const;
static constexpr std::array<Function,sizeof...(Pack)> f = {&Type::get<Pack> ...};
};
template class InstantiateAll<Enum::Member1, Enum::Member2, Enum::Member3>;