通过使用模板模板参数,可以将模板化的类传递给类,而无需在其参数上指定类型.我想知道有没有办法将函数的模板化签名传递给模板模板参数,以便能够专门考虑函数的哪个变体被认为是向前的.
要清楚 - 我知道我做不到:
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.它甚至可能吗?
我无法相信这是不可能的,所以我搜索了一下,找到了一种方法来做我想要的.我使用模板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)
然而,这仍然留下了一个问题,这是如何可能的,因为标准陈述了相反的东西.
在下面的示例中,一个模板模板参数接受函数的首选签名.
由于模板类的特殊化和缺少主体,因此只接受可调用类型.
这是对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)