简体   繁体   English

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

[英]How do I restrict templates to specific types?

For simplicity, say I usually want to pass in strings and basic data types in here: 为了简单起见,假设我通常要在此处传递字符串和基本数据类型:

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

In most cases, I would pass std::string, int, char, float, etc. But say that I don't want it to accept floats. 在大多数情况下,我会传递std :: string,int,char,float等。但是要说我不希望它接受float。 In real world scenarios, I may not want it to accept certain classes. 在现实世界中,我可能不希望它接受某些类。

Is there a way to restrict what the template type accepts? 有没有办法限制模板类型接受的内容?

Yes you can, the most simple way for your example is to put a static_assert in your function. 是的,您可以的,示例的最简单方法是在函数中放入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;
}

This will give you a compile time error if you try and use the function with a float. 如果您尝试将函数与浮点数一起使用,则会产生编译时错误。

Another option is called SFINAE and is used to make the template parameter deduction fail under certain circumstances. 另一个选项称为SFINAE ,用于在某些情况下使模板参数推导失败。

Usually you use std::enable_if in combination with some templates from <type_traits> header. 通常,您将std :: enable_if<type_traits>标头中的某些模板结合使用。 The same thing with SFINAE would look something like: 与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;
}

Let's break down typename std::enable_if<!std::is_same<T, float>::value, int>::type . 让我们分解一下typename std::enable_if<!std::is_same<T, float>::value, int>::type

!std::is_same<T, float>::value is the condition here, if this condition is true this template will have a ::type , otherwise it will not. !std::is_same<T, float>::value是此处的条件,如果此条件为true,则此模板将具有::type ,否则将没有。

After the condition we can specify what we want the type to be if the condition is true, in this case we use int . 在条件之后,我们可以指定条件为true时想要的类型,在这种情况下,我们使用int If this is not specified it will default to void . 如果未指定,则默认为void

So as long as we don't pass a float to this template, the second template parameter will be deduced to int = 0 . 因此,只要我们不将浮点数传递给此模板,第二个模板参数将被推导为int = 0 If we pass in a float the deduction will simply fail and you will get a no matching function error showing the template as a candidate with failed deduction. 如果我们通过浮点数,则推论将简单地失败,并且您将得到一个no matching function错误,将模板显示为推论失败的候选者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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