为简单起见,我想在这里传递字符串和基本数据类型:
template <typename T>
void writeLine(const T &ob)
{
std::cout << ob << std::endl;
}
在大多数情况下,我会传递std :: string,int,char,float等。但是说我不希望它接受浮点数。在现实世界的场景中,我可能不希望它接受某些类。
有没有办法限制模板类型接受的内容?
答案 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
错误,显示该模板是扣除失败的候选人。