通过使用模板模板参数,可以将模板化的类传递给类,而无需在其参数上指定类型。我想知道有没有办法将函数的模板化签名传递给模板模板参数,以便能够专门考虑函数的哪个变体被认为是向前的。
要明确 - 我知道我做不到:
template <class T>
void foo() { /*...*/ }
template <template <class...> class FooType>
struct Foo { /*...*/ };
int main() {
Foo<decltype(foo)> f;
}
但不知何故,我希望能够将模板的函数签名传递给Foo
。它甚至可能吗?
答案 0 :(得分: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;
}
然而,这仍然存在一个问题,即如何这可能是可能的,因为标准陈述了相反的东西。
答案 1 :(得分: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.);
}
答案 2 :(得分:4)
可以在this answer
中看到函数指针模板在C ++中是非法的
C ++标准以14美元/ 1表示,
模板定义了一系列类或函数。
进一步引用相关联的答案:
请注意,它没有说&#34;模板定义了一系列类,函数或函数指针&#34;
但是,您可以传递具体的函数指针,并专注于它们的签名:
#include <iostream>
template <class T>
void foo(T) { }
template <typename>
struct Foo;
template<typename T>
struct Foo<void(T)>
{
void cb() { std::cout << "T\n"; }
};
template<>
struct Foo<void(int)>
{
void cb() { std::cout << "int\n"; }
};
template<>
struct Foo<void(double)>
{
void cb() { std::cout << "double\n"; }
};
int main()
{
Foo<decltype(foo<int >)>().cb(); // outputs 'int'
Foo<decltype(foo<double>)>().cb(); // outputs 'double'
Foo<decltype(foo<char >)>().cb(); // outputs 'T'
return 0;
}
答案 3 :(得分:3)
模板模板仍然是模板。
template <class T>
void foo() { /*...*/ }
template <typename T>
struct Foo { /*...*/ };
int main() {
Foo<decltype(foo<int>)> f;
}
答案 4 :(得分:2)
您无法将函数模板作为参数传递。你可以做的是将一个函数模板包装在一个带有标记参数的生成lambda中:
template <class T> struct tag_t { using type = T; };
template <class T>
void foo() { ... }
template <class F>
void call_func_with(F f) {
f(tag_t<int>{} );
f(tag_t<double>{} );
}
call_with_func([](auto tag) { foo<decltype(tag)::type>(); } );
此处,f(tag_t<X>{} )
最终会根据需要调用foo<X>()
。