【问题标题】:Find the type of a non-type template parameter, based on a template class根据模板类查找非类型模板参数的类型
【发布时间】:2022-01-20 13:51:56
【问题描述】:

给定一个类的形式:

template <int A, int B, int C>
struct Functor {
  static int go() {
    return A*B*C;
  }
};

我需要为 Functor 生成参数的类型的参数包/元组/等。也就是说,我希望能够执行以下操作:

// Imagining that I have many Functor classes...
using FirstArgType = TypeAt<Functor, 1>::T;
FirstArgType t {4};

本质上,我需要从值的参数包转到 unspecialized 模板类的这些值的类型的参数包 - 即 Functor 而不是 Functor&lt;1, 2, 3&gt; .我天真地从看起来像这样的事情开始:

template <template <auto...Values> typename Class>
struct ClassInfo {
   using Tuple = std::tuple<decltype(Values)...>;
};

但是,嵌套的模板-模板参数不能像这样访问 (error: use of undeclared identifier 'Values')。请注意,当我使用 auto...Values 作为顶级模板参数时,这种元组技术可以很好地发现类型 - 问题在于提取 Class 的模板参数。

对于我尝试过的每个公式,我需要在某些时候指定一个完全专业化的类型(例如Functor&lt;1, 2, 3&gt;)以找出类型 - 但我正在尝试操作模板类 Functor,而不是它的特化 Functor&lt;n,n,n&gt; - 我需要模板代码来操作 每个 特化,例如Functor&lt;1, 2, 3&gt;Functor&lt;4, 5, 6&gt;,不只是查找特定专业的类型。

一方面:我觉得我在尝试用 C++ 模板做一些根本不可能的事情——以我不理解的方式——这就是为什么我能想到的每个公式都失败了。

另一方面:很明显Functor 的模板参数类型在编译时是众所周知的,所以我想应该有办法发现这些。

解决方案会很棒,但我同样很高兴听到有关处理我不熟悉的模板-模板参数的策略/技术/设计模式(我不认为自己在这里是专业人士)。

【问题讨论】:

  • 对于上下文:我正在使用来自美妙的 Petra 库 (github.com/jacquelinekay/petra) 的技术来构造切换表,以将运行时值映射到不同的编译时特化函数。因此,务实的目标是使用运行时值调用 functor,例如mapped_functor(1, 2, 3)

标签: c++ templates metaprogramming


【解决方案1】:

你的意思是这样的吗?

#include <tuple>

template <auto... Values>
struct GenericFunctor {
    using Tuple = std::tuple<decltype(Values)...>;
};

using SpecificFunctor = GenericFunctor<short(1), long(2)>;

// Extracts specific template types from functors.
template<class Functor, int i>
using ArgType = decltype(std::get<i>( std::declval<typename Functor::Tuple>() ));

// Instantiate the specific arg type.
static ArgType<SpecificFunctor, 1> t { 1 };

【讨论】:

    【解决方案2】:

    本质上,我需要从值的参数包转到 这些值的类型的参数包。

    您可以使用模板偏特化来提取非类型模板参数的类型,如下所示:

    #include <tuple>
    
    template<auto... args>
    struct Functor {};
    
    template <class>
    struct ClassInfo {};
    
    template <auto... args>
    struct ClassInfo<Functor<args...>> {
      using type = std::tuple<decltype(args)...>;
    };
    
    using F = Functor<0, 42u, 'a', true>;
    static_assert(
      std::is_same_v<ClassInfo<F>::type, std::tuple<int, unsigned, char, bool>>);
    

    Demo.

    【讨论】:

    • 很好的答案,我自己也遇到过这样的事情,但这并不能完全解决问题。这要求您可以参考完全专业的Functor,例如Functor&lt;0, 42u, 'a', true&gt; 查找类型 - 我想对模板类 template&lt;int, int, int&gt; Functor 进行操作 - 我想为 Functor 的每个可能的专业化编写代码。我稍微更新了我的问题 - 希望更清楚一点,我觉得我没有正确使用模板类参数(如 template&lt; &lt;...&gt; typename c&gt;)的术语。
    • @scztt 这是不可能的,因为模板模板参数中auto... Values的范围仅限于Functor模板,我们无法从外部提取它的信息,只有编译器知道。
    猜你喜欢
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 2011-08-06
    • 2014-10-03
    相关资源
    最近更新 更多