有没有办法将模板化的函数签名作为模板模板参数传递

W.F*_*.F. 17 c++ templates

通过使用模板模板参数,可以将模板化的类传递给类,而无需在其参数上指定类型.我想知道有没有办法将函数的模板化签名传递给模板模板参数,以便能够专门考虑函数的哪个变体被认为是向前的.

要清楚 - 我知道我做不到:

template <class T>
void foo() { /*...*/ }

template <template <class...> class FooType>
struct Foo { /*...*/ };

int main() {
    Foo<decltype(foo)> f;
}
Run Code Online (Sandbox Code Playgroud)

但不知何故,我希望能够将模板的模板签名传递给Foo.它甚至可能吗?

W.F*_*.F. 8

我无法相信这是不可能的,所以我搜索了一下,找到了一种方法来做我想要的.我使用模板using语法:

template <template<class... Args> class FooType>
struct Foo {
   FooType<int> ft;
};

template <class Res, class... Args>
using FooSignature = Res(*)(Args...);

int foo() {
   return 1;
}

int main() {
   Foo<FooSignature> f;
   f.ft = foo;
}
Run Code Online (Sandbox Code Playgroud)

然而,这仍然留下了一个问题,这是如何可能的,因为标准陈述了相反的东西.


sky*_*ack 7

在下面的示例中,一个模板模板参数接受函数的首选签名.
由于模板类的特殊化和缺少主体,因此只接受可调用类型.
这是对OP实际问题的概括:

#include<cassert>

template<typename F>
struct S;

template<typename R, typename... Args>
struct S<R(Args...)> {
    using type = R(*)(Args...);
};

template<template<typename> class F>
struct T {
    typename F<void(int)>::type ft;
    typename F<double(double, double)>::type gt;
};

void f(int) { }
double g(double x, double y) { return x+y; }

int main() {
    T<S> t;
    t.ft = f;
    t.gt = g;
    t.ft(42);
    auto v = t.gt(1., 1.);
    assert(v == 2.);
}
Run Code Online (Sandbox Code Playgroud)