c++ - 从类型中提取模板模板的演绎指南

标签 c++ c++17 template-meta-programming template-argument-deduction template-templates

考虑以下类:

// Class definition
template <template <class...> class... Templates>
class template_pack
{
    public:
    template <class... Types>
    constexpr template_pack(const Types&...) noexcept;
};

// Class template argument deduction guide
template <class... Types>
template_pack(const Types&...) -> template_pack</* something here */>

我们假设 Types...形式为 template <class...> class... Templates .我想要的是:

template_pack pack(std::vector<int>{}, std::list<double>{}, std::deque<char>{});

导致:

template_pack<std::vector, std::list, std::deque>;

如何让它发挥作用?

最佳答案

How to make that work?

我看不出有什么办法:总有一些事情是无法推导出来的。

不完全是你问的,但我能想象的最好的通过自定义类型特征传递 ttw (对于“模板-模板-包装器”)

template <template <typename...> class C>
struct ttw
 { 
   template <typename ... Ts>
   constexpr ttw (C<Ts...> const &) 
    { }
 };

使用隐式推导指南,从构造函数接收的类型中提取模板模板,并将其用作模板参数。

所以你可以写template_pack使用接收 ttw<Templates> 的构造函数

template <template <typename...> class... Templates>
struct template_pack
 {
   constexpr template_pack (ttw<Templates> const & ...)
    { }
 };

您可以按如下方式使用(同样:通过隐式演绎指南)

template_pack tp1 {ttw{std::vector<int>{}},
                   ttw{std::set<long>{}},
                   ttw{std::map<char, short>{}}};

问题是有必要在 ttw{} 中显式包装参数因为,举个例子,std::vector<int>可转换为 ttw<std::vector>但不是ttw<std::vector> .所以,通过 std::vector{}而不是 ttw{std::vector{}} ,我们遇到了无法推导的常见鸡/蛋问题,因为要推导它,需要进行转换,该转换需要我们要推导的类型知识。

显然,您可以要求显式 ttw包装适用于特定的 make_template_pack()功能

template <typename ... Ts>
constexpr auto make_template_pack (Ts && ... ts)
 { return template_pack{ttw{std::forward<Ts>(ts)}...}; }

下面是一个完整的编译示例

#include <map>
#include <set>
#include <vector>
#include <type_traits>

template <template <typename...> class C>
struct ttw
 { 
   template <typename ... Ts>
   constexpr ttw (C<Ts...> const &) 
    { }
 };

template <template <typename...> class... Templates>
struct template_pack
 {
   constexpr template_pack (ttw<Templates> const & ...)
    { }
 };

template <typename ... Ts>
constexpr auto make_template_pack (Ts && ... ts)
 { return template_pack{ttw{std::forward<Ts>(ts)}...}; }

int main ()
 { 
   template_pack tp1 {ttw{std::vector<int>{}},
                      ttw{std::set<long>{}},
                      ttw{std::map<char, short>{}}};

   auto tp2 { make_template_pack(std::vector<long>{},
                                 std::set<int>{},
                                 std::map<char, short>{}) };

   using t0 = template_pack<std::vector, std::set, std::map>;
   using t1 = decltype(tp1);
   using t2 = decltype(tp2);

   static_assert( std::is_same<t0, t1>::value );
   static_assert( std::is_same<t0, t2>::value );
 }

关于c++ - 从类型中提取模板模板的演绎指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55997142/

相关文章:

c++ - 代表C++类模板中的空类型

c++ - 模板构造函数

c++ - fetch_add with acq_rel 内存顺序

c++ - 如何将数据从 C++ 数组复制到特征矩阵或 vector ?

C++ VCL 询问 .xlsb Excel 数据库

c++ - 在 C++17 中 i++ + i++ 会评估什么?

c++ - 如何decltype模板方法C++?

c++ - 按位置查找未标记的模板选项/参数/参数

c++ - 返回的std::function保留在std::variant的映射中

c++ - 从模板函数返回默认构造或无效