std :: function模板参数推导

时间:2020-01-14 23:13:22

标签: c++ templates std-function

我为当前问题创建了一个示例。 我希望能够在不指定模板类型的情况下调用以下函数,因为编译器应该能够找出类型:

template<typename T, class Iterable>
void foreach1(std::function<void(T&)> action, Iterable& iterable) {
    std::cout << typeid(T).name() << std::endl;
    for (auto& data : iterable)
        action(data);
}

如果我这样调用函数:

std::vector<int> a = { 1, 2, 3 };
foreach1([](int& data) {
    std::cout << data << std::endl;
}, a);

我得到一个错误。我知道我可以通过以下方式将 std :: function 替换为模板来解决此问题:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable) {
//std::cout << typeid(T).name() << std::endl; // no access to T
for (auto& data : iterable)
    action(data);
}

但是这样做,我无法访问类型 T 。 有没有办法保持对类型 T 的访问并能够使用模板参数推导?

1 个答案:

答案 0 :(得分:3)

将参数传递给类型取决于推导的模板参数的参数时,不允许进行隐式转换。

我建议使用第二个选项:

template<class Action, class Iterable>
void foreach2(Action action, Iterable& iterable)

要确定T,请从std::function中制作一个action

std::function(action)

然后编写模板以获取std::function的参数类型:

template <typename T> struct std_func_param {};
template <typename R, typename T> struct std_func_param<std::function<R(T)>> {using type = T;};
template <typename T> using std_func_param_t = typename std_func_param<T>::type;

像这样使用它:

using T = std_func_param_t<decltype(std::function(action))>;