【问题标题】:How to check if a type is instantiated from a certain variadic template class in a template function?如何检查类型是否从模板函数中的某个可变参数模板类实例化?
【发布时间】:2021-04-29 12:41:23
【问题描述】:

假设我有:

template <typename...>
class Foo { };

然后我定义另一个函数:

template <typename... T>
void Bar(const T&... arguments) { }

如何检查传递给Bar 的所有Ts 是否都从Foo 实例化?喜欢:

Foo<int> a;
Foo<int, int> b;
Bar(a, b); // OK
int c;
Bar(a, b, c); // ill-formed

我想要一种方法来检测格式不正确的参数,例如 Bar(a, b, c); 有没有办法做到这一点?

【问题讨论】:

标签: c++ templates variadic-templates variadic-functions variadic


【解决方案1】:

您可以创建一个特征来测试Foo 的实例化,然后将其折叠到您的所有参数中。

template <typename>
struct is_foo : std::false_type {};

template <typename... Ts>
struct is_foo<Foo<Ts...>> : std::true_type {};

template <typename T>
constexpr bool is_foo_v = is_foo<T>::value;

template <typename... T>
void Bar(const T&... arguments) {
    static_assert((is_foo_v<T> && ...), "arguments must all be Foos");
}

See it on coliru

【讨论】:

  • 如果我理解正确,如果TFoo&lt;int&gt;constexpr bool 的计算结果为constexpr bool is_foo_v = is_foo&lt;Foo&lt;int&gt;&gt;::value;,那么编译器会选择第二个is_foo,因为它有点像“更有效”?另外,我认为第二个 is_foo 不需要是可变参数模板结构,还是我遗漏了什么?
  • 特化匹配所有Foo 实例化,仅此而已。它复制Foo的模板参数
  • @palapapa 看Partial Specialisation,当is_foo&lt;Foo&lt;int&gt;&gt;被编译时,继承true_type的特化匹配,Ts...等于int
  • 是的,Ts... 是匹配Foo&lt;int, int&gt; 等中的int, intis_foo 模板中没有T。主模板中有一个未命名的模板参数,部分特化匹配Foo那里的任何实例化
  • 你可以有进一步的专业化,例如对于Foo 至少有一个int 参数template &lt;typename... Ts, typename... Us&gt; struct is_foo&lt;Ts..., int, Us...&gt; /* something*/
猜你喜欢
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 2018-10-23
  • 2013-10-02
相关资源
最近更新 更多