我正在尝试定义一种模板'map'原语(如map-reduce) . 我的想法是我想将一个函数应用于模板参数包的每个项目 . 该函数可以是任何可调用对象 . 它可以返回任何类型(虽然返回类型将被忽略),并且它可以在有问题的项目之上采取其他参数 .
棘手的部分是我有效地拥有两个需要处理的参数包 . 它们最初会被打包在一起,但我想使用模板特化来拆分它们 . 以下是我尝试这样做的尝试 .
如果不明显(由于模板参数列表中的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...);
不幸的是,当我尝试编译它(使用clang)时,我收到以下错误 .
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.
现在,我不会喜欢 ArgumentTypes...
在我的专业化中出现两次这一事实,尽管它没有直接说出来 .
What exactly is going wrong, and how might I build my map primitive in a way that avoid this? 我不需要 . 如果我手动编写专门用于函数和参数类型的模板,我不需要存储任何东西 . 这排除了元组包装器作为选项 .
编辑:根据要求添加使用信息 .
编辑:修复过度使用右值参考限定符,以避免混淆 .
1 回答
有几个问题因此可能更容易从一个有效的简单基本示例开始(没有完美的转发) .
您可以分离参数包:
参数类型作为
Map
的模板参数传递项类型作为
Map::function
的模板参数传递这是一个没有完美转发的工作示例 . 由于可能的cv限定符和ref限定符,因此推论参数类型并不完整 .
输出: