Специализация шаблонного класса с std :: enable_if и конкретным типом - PullRequest
2 голосов
/ 08 апреля 2019

У меня есть JsonFormatter шаблонный класс, который специализируется для различных типов, таких как арифметика и т. Д., Следующим образом:

template <class T, typename Enable = void>
class JsonFormatter;

template <class T>
class JsonFormatter<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
{
};

Непонятно, как специализировать его для конкретного типа типа std::string, например? Моей первой идеей было что-то вроде этого:

template <>
class JsonFormatter<std::string, std::true_type>
{
};

но это не компилируется. Когда я использую

JsonFormatter<std::string>

Я получаю

"undefined class 'JsonFormatter<std::string,void>'"

Ответы [ 3 ]

4 голосов
/ 08 апреля 2019

Важным моментом является то, что специализация должна соответствовать основной.В этом случае первичный настраивается так, что второй параметр шаблона будет void - он не предназначен для предоставления пользователем, он просто позволяет людям использовать enable_if.

* 1004.*std::true_type не соответствует void, поэтому не работает.Когда пользователь пишет JsonFormatter<std::string>, аргумент по умолчанию будет создан как void - поэтому он ищет специализацию JsonFormatter<std::string, void> ... которая не соответствует той, которую вы указали.

Вы хотите:

template <>
class JsonFormatter<std::string, void>
{ };

Или даже просто:

template <>
class JsonFormatter<std::string>
{ };

Поскольку аргумент по умолчанию будет заполнен просто отлично.

1 голос
/ 08 апреля 2019

Непонятно, как специализировать его для конкретного типа, например std::string?

Вы пробовали просто с

template <>
class JsonFormatter<std::string>
{
};

?

Должно работать.

Второй параметр шаблона становится void в соответствии с ошибкойзначение определено в основной версии.

1 голос
/ 08 апреля 2019

Вот как вы специализируете шаблон:

template <>
class JsonFormatter<std::string, void>
{
};

Вы также можете использовать std::enable_if, но я не рекомендую его, поскольку его простая специализация намного проще.std::enable_if работает правильно только с SFINAE .Так что это должно зависеть от параметра шаблона:

template <class T>
class JsonFormatter<T, std::enable_if_t<std::is_same_v<T, std::string>>>
{
};
...