当前位置: 首页 > 知识库问答 >
问题:

使用模板专门化拆分可变参数包

胡飞舟
2023-03-14

棘手的部分是,我实际上有两个参数包,我需要处理。它们最初将打包在一起,但我想使用模板专门化来拆分它们。接下来是我做这件事的尝试。

如果它不明显(由于模板参数列表中的auto关键字),这是使用C++17。

#include <utility>

template <class Signature, auto f, class... ArgsAndItems>
struct Map;

template
<
    class ReturnType,
    class Item,
    class... ArgumentTypes,
    auto f,
    class... Items
>
struct Map
<
    ReturnType (Item, ArgumentTypes...),
    f,
    ArgumentTypes...,
    Item,
    Items...
>
{
    static void
    function (ArgumentTypes &&... arguments, Item && item, Items &&... items);
};

template <class ReturnType, class Item, class... ArgumentTypes, auto f>
struct Map<ReturnType (Item, ArgumentTypes...), f, ArgumentTypes...>
{
    static void
    function (ArgumentTypes &&... arguments);
};

template
<
    class ReturnType,
    class Item,
    class... ArgumentTypes,
    auto f,
    class... Items
>
void
Map
<
    ReturnType (Item, ArgumentTypes...),
    f,
    ArgumentTypes...,
    Item,
    Items...
>::function (ArgumentTypes &&... arguments, Item && item, Items &&... items)
{
    f (std::forward<Item> (item), std::forward<ArgumentTypes> (arguments)...);
    Map
    <
        ReturnType (Item, ArgumentTypes ...),
        f,
        ArgumentTypes...,
        Items...
    >::function
    (
        std::forward<ArgumentTypes> (arguments)...,
        std::forward<Items> (items)...
    );
}

template <class ReturnType, class Item, class... ArgumentTypes, auto f>
void
Map
<
    ReturnType (Item, ArgumentTypes...),
    f,
    ArgumentTypes...
>::function (ArgumentTypes &&... arguments)
{
}

这个想法是有一个包装器,它看起来像

template <auto f, class ... ArgsAndItems>
void
map (ArgsAndItems && ... args_and_items)
{
    Map
    <
        decltype (decltype (f)::operator ()),
        f,
        ArgsAndItems...
    >::function (std::forward <ArgsAndItems> (args_and_items) ...);
}
map <foo> (args_for_foo..., items_to_map_over...);
map.hpp:14:8: error: class template partial specialization contains template
      parameters that cannot be deduced; this partial specialization will never
      be used
      [-Wunusable-partial-specialization]
struct Map
       ^~~
map.hpp:8:8: note: non-deducible template parameter 'ReturnType'
        class ReturnType,
              ^
map.hpp:9:8: note: non-deducible template parameter 'Item'
        class Item,
              ^
map.hpp:10:11: note: non-deducible template parameter 'ArgumentTypes'
        class... ArgumentTypes,
                 ^
map.hpp:11:7: note: non-deducible template parameter 'f'
        auto f,
             ^
map.hpp:12:11: note: non-deducible template parameter 'Items'
        class... Items
                 ^
1 error generated.

编辑:修正了rvalue引用限定符的过度使用,以避免混淆。

共有1个答案

子车青青
2023-03-14

到底出了什么问题,[...]

有几个问题,所以从一个简单的基本示例开始可能更容易(没有完美的转发)。

[...]我怎样才能以避免这种情况的方式构建我的地图原语呢?

    null
#include <iostream>

template<class F, class... Args>
struct Map {
  template<class... Items>
  static void function(Args... args, Items... items) {
    static constexpr auto f = F{};

    // here comes a fold expression
    // see https://en.cppreference.com/w/cpp/language/fold

    ( f(items, args...), ...); // "fold over comma operator"
  }
};

////////////////////////////////////////////////////////////////////////////////

template<class F, class Ret, class Item, class... Args, class... ArgsItems>
void map_impl(Ret(F::*)(Item, Args...) const, ArgsItems... args_items) {
  Map<F, Args...>::function(args_items...);
}

template<class F, class... ArgsItems>
void map(ArgsItems... args_items) {
  map_impl<F>(&F::operator(), args_items...);
}

////////////////////////////////////////////////////////////////////////////////

struct print_x_m_plus_n {
  void operator()(int x, int m, int n) const {
    int y = x * m + n;
    std::cout << y << std::endl;
  }
};

int main() {
  constexpr int m = 2;
  constexpr int n = 1;

  map<print_x_m_plus_n>(m, n, 0, 1, 2);
}
1
3
5
 类似资料:
  • 我试图编写一个可变函数模板来计算的字节大小。这将用于一个网络编程项目,我正在工作。第一步,我在没有工作的variadic模板的情况下想出了这个: 错误代码#2。如果我将variadic模板放在不同的位置: 我得到了 错误:重载的'size t ()'调用不明确

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 我有一段代码,它是做模板专门化的常用模式。为了移除main函数第一行中为Processor1指定DataType1的要求,我想改为接收一个template模板参数。看起来using指令不支持分配“open”模板参数,而且我在web中找不到任何这样的示例(可能我没有使用适当的关键字进行搜索...) 所以问题很“简单”,我如何让这段代码编译呢?在FindDefaultProcessor中,使用type

  • 也许我累了,但是我被这个简单的局部特化卡住了,它不起作用,因为指定模板参数: 将替换为,或没有帮助。那么这种专门化是否可能呢?

  • 请向我解释选择模板专用化的规则。我举一个例子: 为什么输出为?一般来说,专用类中的默认模板参数会发生什么情况?它会带来一些影响吗?