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

C++ 有没有办法将模板函数签名作为模板参数传递,c++,templates,C++,Templates,通过使用模板参数,可以将模板类传递给类,而无需在其参数上指定类型。我想知道是否有一种方法可以将一个函数的模板签名传递到模板参数中,从而能够专门化该函数的哪个变量被认为是向前的 明确地说,我知道我不能这么做: template <class T> void foo() { /*...*/ } template <template <class...> class FooType> struct Foo { /*...*/ }; int main() {

通过使用模板参数,可以将模板类传递给类,而无需在其参数上指定类型。我想知道是否有一种方法可以将一个函数的模板签名传递到模板参数中,从而能够专门化该函数的哪个变量被认为是向前的

明确地说,我知道我不能这么做:

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

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

int main() {
    Foo<decltype(foo)> f;
}
模板
void foo(){/*…*/}
模板
结构Foo{/*…*/};
int main(){
福福;
}

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

模板的模板仍然是一个模板

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

template <typename T>
struct Foo { /*...*/ };

int main() {
    Foo<decltype(foo<int>)> f;
}
模板
void foo(){/*…*/}
模板
结构Foo{/*…*/};
int main(){
福福;
}
如图所示

函数指针的模板在C中是非法的++

< C++标准中说,14/1美元,

模板定义了一系列类或函数

进一步引用链接答案:

请注意,它并没有说“模板定义了一系列类、函数或函数指针。”

但是,您可以传递具体的函数指针,并专门处理它们的签名:

#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;
}
#包括
模板
void foo(T){}
模板
结构Foo;
模板
结构Foo
{

void cb(){std::cout您不能将函数模板作为参数传递。您可以做的是将函数模板包装到带有标记参数的generate 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>(); } );
模板结构标记{using type=t;};
模板
void foo(){…}
模板
带(F)的无效调用函数{
f(tag_t{});
f(tag_t{});
}
使用_func([](自动标记){foo();})调用_;

在这里,
f(tag_t{})
根据需要调用
foo()

我不敢相信这是不可能的,所以我搜索了一下,找到了一种方法来完全实现我想要的。我使用了模板化的
,使用了一种语法:

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;
}
模板
结构Foo{
足型ft;
};
模板
使用FooSignature=Res(*)(Args…);
int foo(){
返回1;
}
int main(){
福福;
f、 ft=foo;
}

然而,这仍然留下了一个问题:既然标准规定了相反的内容,这怎么可能呢。

在下面的示例中,有一个模板参数接受函数的首选签名。
由于模板类的专门化和缺少主体,因此只接受可调用的类型。
它概括了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.);
}
#包括
模板
结构;
模板
结构{
使用type=R(*)(Args…);
};
模板
结构T{
类型名F::类型ft;
typename F::type gt;
};
空f(int){}
双g(双x,双y){返回x+y;}
int main(){
T;
t、 ft=f;
t、 gt=g;
t、 ft(42);
自动v=t.gt(1,1.);
断言(v==2);
}

是的,
使用
在这里起到了作用。这种方法似乎比模板化的
使用
更干净……我能问一下你使用它的目的吗?只是好奇……我看不出
t
有什么用处,因为我不能简单地使用
S
。当然,这个问题来自另一个存档问题:我想提出一个问题通用标记,可以接受模板类和具有给定签名的函数…然后我意识到这不是一个简单的任务…:)