полная специализация шаблонных функций с параметром std :: if_enabled_t - PullRequest
1 голос
/ 26 апреля 2020

Я пытаюсь написать функцию, которая реализует общее поведение для всех типов, которые не являются перечислениями, общее поведение для всех типов, которые являются перечислениями, а затем возможность специализовать определенное c поведение для некоторых типов с помощью полностью специализирующаяся на функции. Вот мой код:

// 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>();
}

Он не компилируется, и я действительно не знаю, как это сделать правильно. Если я позволю специализированному прототипу, как в коде выше, я получу эту ошибку компоновки:

error LNK2005: "void __cdecl Func<bool,0>(void)" (??$Func@_N$0A@@@YAXXZ) already defined in main.obj

, и если я сделаю специализированный прототип template<> void Func<bool, nullptr>(), я получу эту ошибку компиляции:

error C2912: explicit specialization 'void Func<bool,nullptr>(void)' is not a specialization of a function template

Эти тесты выполняются с использованием компилятора Visual Studio 2015 со стандартом c ++ 14

Я не знаю, куда отсюда go, любая помощь будет принята с благодарностью

1 Ответ

2 голосов
/ 26 апреля 2020

Вы получаете ошибку компоновки, потому что Func<bool>() определено в заголовочном файле, который включен в несколько модулей компиляции. Решение простое: поместите inline перед void Func<bool>():

template<>
inline void Func<bool>()
{
    // ...
}

Шаблоны функций неявно inline, но функции и явные специализации шаблонов не, Если они определены в заголовочном файле, они должны быть помечены как inline.

...