简体   繁体   English

如何检查模板参数的类型?

[英]How to check for the type of a template parameter?

Suppose I have a template function and two classes假设我有一个模板函数和两个类

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

How do I do the check for T is animal?如何检查 T is animal? I don't want to have something that checks during the run time.我不想在运行时进行检查。 Thanks谢谢

Use is_same :使用is_same

#include <type_traits>

template <typename T>
void foo()
{
    if (std::is_same<T, animal>::value) { /* ... */ }  // optimizable...
}

Usually, that's a totally unworkable design, though, and you really want to specialize :通常,这是一个完全不可行的设计,但你真的想专攻

template <typename T> void foo() { /* generic implementation  */ }

template <> void foo<animal>()   { /* specific for T = animal */ }

Note also that it's unusual to have function templates with explicit (non-deduced) arguments.另请注意,具有显式(非推导)参数的函数模板是不常见的。 It's not unheard of, but often there are better approaches.这并非闻所未闻,但通常有更好的方法。

I think todays, it is better to use, but only with C++17.我认为今天,它更好用,但仅限于 C++17。

#include <type_traits>

template <typename T>
void foo() {
    if constexpr (std::is_same_v<T, animal>) {
        // use type specific operations... 
    } 
}

If you use some type specific operations in if expression body without constexpr , this code will not compile.如果您在没有constexpr的 if 表达式主体中使用某些类型特定的操作,则此代码将无法编译。

You can specialize your templates based on what's passed into their parameters like this:您可以根据传递给模板的参数来专门化您的模板,如下所示:

template <> void foo<animal> {

}

Note that this creates an entirely new function based on the type that's passed as T .请注意,这会根据作为T传递的类型创建一个全新的函数。 This is usually preferable as it reduces clutter and is essentially the reason we have templates in the first place.这通常是可取的,因为它减少了混乱,并且本质上是我们首先拥有模板的原因。

std::is_same() is only available since C++11. std::is_same()仅在 C++11 之后可用。 For pre-C++11 you can use typeid() :对于 C++11 之前的版本,您可以使用typeid()

template <typename T>
void foo()
{
    if (typeid(T) == typeid(animal)) { /* ... */ }
}

In C++17, we can use variants .在 C++17 中,我们可以使用variants

To use std::variant , you need to include the header:要使用std::variant ,您需要包含标头:

#include <variant>

After that, you may add std::variant in your code like this:之后,您可以像这样在代码中添加std::variant

using Type = std::variant<Animal, Person>;

template <class T>
void foo(Type type) {
    if (std::is_same_v<type, Animal>) {
        // Do stuff...
    } else {
        // Do stuff...
    }
}

use c++ concepts https://en.cppreference.com/w/cpp/language/constraints使用 C++ 概念https://en.cppreference.com/w/cpp/language/constraints

for example class who recive only char types例如只接受 char 类型的类

#include <concepts>

 template<typename Type>
    concept CharTypes = std::is_same<Type, char>::value ||
                        std::is_same<Type, wchar_t>::value || std::is_same<Type, char8_t>::value ||
                        std::is_same<Type, char16_t>::value || std::is_same<Type, char32_t>::value;

template<CharTypes T>
    class Some{};

and yes, this not working是的,这不起作用


    Some<int> s;

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

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