仅匹配某些类型的模板函数? [英] Template function that matches only certain types?

查看:34
本文介绍了仅匹配某些类型的模板函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个函数模板:

I want to define a function template:

template<typename T>
void foo(T arg)

但我希望 T 只匹配某些类型.具体来说,T 应该从某个基类派生(可能通过多重继承).否则,此模板不应包含在重载集中.

But I want T to match only certain types. Specifically, T should derive (maybe through multiple inheritance) form a certain base class. Otherwise this template shouldn't be included in the overload set.

我该怎么做?

推荐答案

使用 SFINAE 和 <代码>std::is_base_of:

Use SFINAE with std::is_base_of:

template <typename T,
          typename = std::enable_if_t<
              std::is_base_of<Foo, T>::value
          >>
void foo(T arg);

如果T 继承自Foo,那么它只会在重载集中包含foo.请注意,这也包括模棱两可和不可访问的基础.如果您想要一个仅允许 TFoo 继承公开明确的解决方案,那么您可以而是使用 std::is_convertible:

That will only include foo in the overload set if T inherits from Foo. Note that this includes ambiguous and inaccessible bases as well. If you want a solution that only allows for Ts that inherit publicly and unambiguously from Foo, then you can instead use std::is_convertible:

template <typename T,
          typename = std::enable_if_t<
              std::is_convertible<T*, Foo*>::value
          >>
void foo(T arg);

注意参数的颠倒.

无论您选择哪种形式,都可以为简洁起见使用别名:

Regardless of which form you pick, it can be aliased for brevity:

template <typename T>
using enable_if_foo = std::enable_if_t<std::is_base_of<Foo, T>::value>;

template <typename T,
          typename = enable_if_foo<T>>
void foo(T arg);


这是有效的,因为 std::enable_if有一个名为 type 的嵌套类型,当且仅当传入的布尔值为 true.所以如果 std::is_base_of::valuetrueenable_if_t 被实例化为 void,就好像我们写过:


This works because std::enable_if has a nested type named type if and only if the boolean passed in is true. So if std::is_base_of<Foo, T>::value is true, enable_if_t gets instantiated to void, as if we had written:

template <typename T,
          typename = void>
void foo(T arg);

但是,如果 T 不继承自 Foo,那么类型特征将评估为 false,并且 std::enable_if_t 是替换失败 - 没有 typename enable_if::type.您可能会认为这是一个编译错误,但是 s替换 failure is not an e错误(sfinae).只是模板推导失败.因此,在这种情况下,效果是 foo 只是从可行的重载候选集中删除,与任何其他模板推导失败没有什么不同.

But, if T does not inherit from Foo, then the type trait will evaluate as false, and std::enable_if_t<false> is a substitution failure - there is no typename enable_if<false>::type. You might expect this to a compile error, but substitution failure is not an error (sfinae). It's just a template deduction failure. So the effect is that foo<T> is simply removed from the set of viable overload candidates in this case, no different from any other template deduction failure.

这篇关于仅匹配某些类型的模板函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆