【发布时间】:2018-11-22 20:50:38
【问题描述】:
我正在尝试定义一种模板“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... 在我的专业中出现两次这一事实,我不会感到惊讶,尽管它没有直接这么说。
究竟出了什么问题,我该如何构建我的地图原语以避免这种情况?我不想存储任何参数的副本或引用,因为那不应该没必要。如果我手动编写一个专门用于函数和参数类型的模板,我就不需要存储任何东西。这排除了元组包装器作为选项。
编辑:根据要求添加了使用信息。
编辑:修复了过度使用右值引用限定符的问题,以避免混淆。
【问题讨论】:
-
请注意,您使用的是 rvalue-references 而不是 forwarding references。
-
@Jarod42:哎呀。这基本上是一个错字。我现在已经解决了。
标签: c++ c++17 variadic-templates template-specialization partial-specialization