- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试定义一种模板“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...
在我的特化中出现两次这一事实,我不会感到惊讶,尽管它并没有直接这么说。
到底出了什么问题,我该如何构建我的 map 原语才能避免这种情况?我不想存储任何参数的拷贝或引用,因为那不应该有必要。如果我手动编写专门用于函数和参数类型的模板,则不需要存储任何内容。这排除了元组包装器作为一个选项。
编辑:根据要求添加了使用信息。
编辑:修复了过度使用右值引用限定符,以避免混淆。
最佳答案
What exactly is going wrong, [...]
有几个问题,因此从一个有效的简单基本示例开始可能更容易(没有完美的转发)。
[...] and how might I build my map primitive in a way that avoid this?
您可以将参数包分开:
Map
的模板参数传递Map::function
的模板参数传递这是一个没有完美转发的工作示例。由于可能的 cv 限定符和 ref 限定符,关于参数类型的推导并不完整。
#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
关于c++ - 使用模板特化拆分可变参数包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53437838/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!