具有std :: enable_if和具体类型的模板类专门化

时间:2019-04-08 19:28:56

标签: c++ templates c++17 sfinae

我有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 个答案:

答案 0 :(得分:4)

重要的一点是,专业化必须与主要匹配。在这种情况下,主要对象的设置应使第二个模板参数将为void-用户不打算提供它,而是为了使人们能够使用enable_if。< / p>

std::true_typevoid不匹配,这就是为什么它不起作用的原因。当用户编写JsonFormatter<std::string>时,默认参数将实例化为void-因此,他们正在寻找专业化JsonFormatter<std::string, void> ...这不是您提供的。

您要

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

甚至只是:

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

因为默认参数将被很好地填充。

答案 1 :(得分:1)

这是您专门化模板的方式:

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>>>
{
};

答案 2 :(得分:1)

  

例如,如何将其专门化为std::string这样的具体类型还不清楚?

您是否尝试过简单

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

应该可以。

根据主版本中定义的dafault值,第二个模板参数变为void