简体   繁体   English

是否有任何解决方法可以将 function 模板作为模板参数传递?

[英]Is there any workaround for passing a function template as a template parameter?

I'm trying to make a function template that takes a function template as a template argument and then returns the result of that function when invoked with the normal function parameters passed in. It would be used like this: I'm trying to make a function template that takes a function template as a template argument and then returns the result of that function when invoked with the normal function parameters passed in. It would be used like this:

auto fooPtr = func<std::make_unique, Foo>(...);

The point of the function is to allow template type deduction even when letting another function perform construction of an instance. function 的要点是即使在让另一个 function 执行实例的构造时也允许模板类型推导。 I already do this manually in a lot of places in my code like this:我已经在我的代码中的很多地方手动执行此操作,如下所示:

auto fooPtr = std::make_unique<decltype(Foo{...})>(...);

I got the idea of a helper function from this answer to a question I posted.我从这个对我发布的问题的回答中得到了帮助者 function 的想法。 He suggested to make one for a specific type but I want a function that can be used for any type.他建议为特定类型制作一个,但我想要一个可用于任何类型的 function。

Here's what I've come up with so far:到目前为止,这是我想出的:

template
<auto F, template<typename U> class T, typename... Args>
std::result_of_t<decltype(F)> 
func(Args&&... args, std::enable_if_t<std::is_invocable_v<decltype(F), Args...>>* = nullptr)
{
    return F<decltype(T{std::forward<Args>(args)...})>(std::forward<Args>(args)...);
}

But I can't get it to work.但我无法让它工作。

Am I on the right track?我在正确的轨道上吗? Is what I'm trying to do even possible?我想要做的甚至可能吗?

You can't pass a templated function as a template argument unfortunately unless you specify the template arguments explicitly, eg:不幸的是,除非您明确指定模板 arguments,否则您不能将模板化 function 作为模板参数传递,例如:

template<auto T>
auto func(auto&&... args) {
    return T(std::forward<decltype(args)>(args)...);
}

struct Foo { Foo(int i) {} };

int main() {
    auto unique_foo = func<std::make_unique<Foo, int>>(1);
}

You can however pass around templated function objects without problems, so the following would work:但是,您可以毫无问题地传递模板化的 function 对象,因此以下方法可行:

template<class T>
struct unique {
    auto operator()(auto&&... args) {
        return std::make_unique<T>(std::forward<decltype(args)>(args)...);
    }
};

template<class T>
struct shared {
    auto operator()(auto&&... args) {
        return std::make_shared<T>(std::forward<decltype(args)>(args)...);
    }
};

template<template<class> class F, class T, class... Args>
  requires std::is_invocable_v<F<T>, Args...>
auto func(Args&&... args) {
    return F<T>{}(std::forward<Args>(args)...);
}

struct Foo { Foo(int i) {} };

int main(){
    auto foo_unique = func<unique, Foo>(1);
    auto foo_shared = func<shared, Foo>(2);
}

godbolt example螺栓示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM