简体   繁体   中英

Template class specialization with std::enable_if and a concrete type

I have JsonFormatter template class that is specialized for different types like arithmetic etc... in the following way:

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

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

it is not clear how to specialize it for a concrete type like std::string , for example? My first idea was something like this:

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

but this does not compile. When I use

JsonFormatter<std::string>

I get

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

The important point is that the specialization has to match the primary. In this case, the primary is set up such that the 2nd template parameter is going to be void - it's not intended to be provided by the user, it's just there to enable people to use enable_if .

std::true_type doesn't match void , which is why it doesn't work. When the user writes JsonFormatter<std::string> , the default argument will get instantiated as void - so they're looking for the specialization JsonFormatter<std::string, void> ... which isn't what you provided.

You want:

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

Or even just:

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

Since the default argument will get filled in just fine.

This is how you specialize the template:

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

You can also use std::enable_if , but I don't recommend it since it a simple specialization is much easier. std::enable_if works correctly with SFINAE only. So it needs to depend on a template parameter:

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

it is not clear how to specialize it for a concrete type like std::string , for example?

Have you tried simply with

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

?

Should works.

The second template parameter become void according the dafault value defined in the main version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM