【问题标题】:Is there a way to get type of template class from its complete type?有没有办法从其完整类型中获取模板类的类型?
【发布时间】:2020-07-31 08:53:40
【问题描述】:

我需要一个针对给定完整类类型返回其模板的元函数(例如,f<foo<bar>>::type 或 f<foo<baz>>::type 导致 foo)。

或者它可能会在 f<foo<bar>, foo<baz>>::value 上返回 true 和在 f<foo<bar>, not_foo<baz>>::value 上返回 false

P.S:这意味着要与许多类似 chrono::duration 的类一起使用(但用于重量单位、质量单位等)。我需要不同的单位而不是将一个单位转换为另一个单位。

【问题讨论】:

  • 或者它可能在f<foo<bar>, foo<baz>>::value 和false 上返回true f<foo1<bar>, foo2<bar>>::value
  • 您在寻找decltype吗?
  • 你可以edit你的问题而不是添加cmets。
  • decltype 将导致完整类型 foo<bar> 而不是 foo
  • 获得true 和false 的类型特征可以完成,获得foo 无需先提及我不确定它是否可能。 is_instantiation_of_foo < foo<bar> > 就足够了吗?

标签: c++ c++11 templates metaprogramming template-meta-programming


【解决方案1】:

f<foo<bar>>::type or f<foo<baz>>::type results in foo

不完全是(见is-an-alias-template-considered-equal-to-the-same-template),你可以这样做:

template <typename T> struct template_class;

template <template <typename> class C, typename T>
struct template_class<C<T>>
{
    template <typename U>
    using type = C<U>;
};

或者它可能在f&lt;foo&lt;bar&gt;, foo&lt;baz&gt;&gt;::value 上返回真,在f&lt;foo&lt;bar&gt;, not_foo&lt;baz&gt;&gt;::value 上返回假

更容易,即使有限,专业化主要是is_same:

template <typename, typename> struct has_same_template_class : std::false_type{};

template <template<typename> class C, typename T1, typename T2>
struct has_same_template_class<C<T1>, C<T2>> : std::true_type{};

【讨论】:

  • 为什么“不完全”?我试图完全做到这一点,但没有成功。你的template_class 可以用来从template_class&lt; foo&lt;int&gt;&gt;::type 得到foo,这不是OP 要求的吗?当然,模板没有太多可做的,但例如可以写一个is_same_template 来查看is_same_template&lt; foo, template_class&lt; foo&lt;int&gt; &gt;::value 真的是true (godbolt.org/z/nNvtKz)
  • @idclev463035818 Clang 不同意。考虑到所有因素,我认为该标准不需要实现来实现函数的任意相等(鉴于这是不可能的),因此 正确 结果是false,“实现-已定义”或“未定义”,都不可取。
  • @HTNW 抱歉,我不完全理解您所说的。 “任意相等的功能”?不涉及任何功能。我去看看clang,说不定我就明白了……
  • @HTNW 我想你的意思是模板,而不是函数。现在我明白了,type 模板别名与foo 的模板并不完全相同,它只是“看起来”。现在我很好奇它的具体实现是什么,也许我会提出一个问题
  • @idclev463035818 模板是数学函数的一种形式。给定两个具有无限域(可以输入的类型无限多)的任意函数(模板),根本无法确定它们是否在每个点都相等(扩展相等)。由于我们所有的函数都可以用有限多个符号(用于编写它们的实际语法)写出,您可以轻松获得更强的内涵相等,您可以在其中检查“语法”或“身份” " 是一样的。
【解决方案2】:

你可能想要这样的东西:

#include <type_traits>

template<class> struct foo;
template<class> struct not_foo;

struct bar;
struct baz;

template<class, class>
struct trait : std::false_type {};

template<template<class> class T, class S1, class S2>
struct trait<T<S1>, T<S2>> : std::true_type {};

static_assert( trait<foo<bar>,     foo<baz>    >::value);
static_assert( trait<not_foo<bar>, not_foo<baz>>::value);
static_assert(!trait<foo<bar>,     not_foo<baz>>::value);
static_assert(!trait<foo<bar>,     not_foo<bar>>::value);

Demo

【讨论】:

  • 这不适用于多个模板参数,对吧?
  • @sparik,正如所写,它不会。但是你可以写template&lt;template&lt;class...&gt; class T, class... S1, class... S2&gt; struct trait&lt;T&lt;S1...&gt;, T&lt;S2...&gt;&gt;。
  • 这确实是第二个问题的解法!谢谢。
猜你喜欢
  • 2017-02-10
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多