如何将模板限制为特定类型?

时间:2018-03-16 23:10:28

标签: c++

为简单起见,我想在这里传递字符串和基本数据类型:

template <typename T>
void writeLine(const T &ob)
{
    std::cout << ob << std::endl;
}

在大多数情况下,我会传递std :: string,int,char,float等。但是说我不希望它接受浮点数。在现实世界的场景中,我可能不希望它接受某些类。

有没有办法限制模板类型接受的内容?

1 个答案:

答案 0 :(得分:2)

是的,你可以,你的例子最简单的方法是在你的函数中添加static_assert

template <typename T>
void writeLine(const T &ob)
{
    static_assert(!std::is_same<T, float>::value, "You can't use floats here");
    std::cout << ob << std::endl;
}

如果您尝试使用带浮点函数的函数,这将给出编译时错误。

另一个选项称为SFINAE,用于在某些情况下使模板参数扣除失败。

通常您会将std::enable_if<type_traits>标题中的某些模板结合使用。与SFINAE相同的是:

template <typename T, typename std::enable_if<!std::is_same<T, float>::value, int>::type = 0>
void writeLine(const T &ob)
{
    std::cout << ob << std::endl;
}

让我们分解typename std::enable_if<!std::is_same<T, float>::value, int>::type

!std::is_same<T, float>::value是此处的条件,如果此条件为真,则此模板将具有::type,否则不会。{/ p>

在条件之后,如果条件为真,我们可以指定我们想要的类型,在这种情况下我们使用int。如果未指定,则默认为void

因此,只要我们不将浮点数传递给此模板,第二个模板参数就会推导到int = 0。如果我们传入一个浮点数,则扣除将会失败,您将收到no matching function错误,显示该模板是扣除失败的候选人。

相关问题