【发布时间】:2019-01-17 04:34:13
【问题描述】:
我正在尝试使用用于处理它们的函数的类型信息从数组元组中检索值。但是,在这种情况下,类型推导失败(部分原因是?)因为需要为std::function 的类型名使用标识结构。这里有没有办法恢复扣款?
#include <functional>
#include <iostream>
#include <tuple>
class comp_a
{
public:
static const size_t id = 0;
int val = 0;
};
class comp_b
{
public:
static const size_t id = 1;
int val = 0;
};
class comp_c
{
public:
static const size_t id = 2;
int val = 0;
};
template<size_t size, typename ... Cs>
struct storage
{
template<typename T> struct identity { using type = T; };
template<typename ... Ts>
void get(size_t index, typename identity<std::function<void(Ts& ...)>>::type f)
{
f(std::get<Ts::id>(components)[index] ...);
}
std::tuple<std::array<Cs, size> ...> components;
};
int32_t main()
{
storage<20, comp_a, comp_b, comp_c> storage;
storage.get(2, [](comp_a& a, comp_c& c) { // Doesn't work
// storage.get<comp_a, comp_c>(2, [](comp_a& a, comp_c& c) { // Works
std::cout << a.val << " " << c.val << std::endl;
});
}
我遇到过this 和this,它们看起来很相似,但我相信我的情况有所不同,因为我需要可变参数类型才能在检索所需值时访问它们的特征。在这些示例中,函数的可变参数被视为 void:
error: cannot convert 'main()::<lambda(comp_a&, comp_c&)>' to 'storage<20, comp_a, comp_b, comp_c>::identity<std::function<void()> >::type' {aka 'std::function<void()>'}
在这种情况下,扣除指南是否可行?类型信息似乎隐藏在 std::function 的类型中有点深,所以我不确定如何在指南中将其提取出来。
here 提供了一个实时示例。
【问题讨论】:
-
我无法回答您的具体问题,但为什么要使用
std::function?你不能使用identity<void(Ts&...)>::type(甚至void(Ts&...)吗? -
遗憾的是,常规函数指针不起作用,因为 AFAIK 它排除了 lambda 内的任何捕获(我想做的事情,尽管在这个例子中我不这样做)。当我尝试它时,它似乎也失败了参数推导。通过身份运行它会出现同样的问题,即推导对函数参数视而不见。
-
身份类型的一种用途正是您要避免的。它使您的论点不可演绎,因此必须在模板类型列表中指定它。所以我不确定它为什么在那里......
标签: c++ templates c++17 variadic-templates std-function