Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否有一种通用方法将函数模板调整为多态函数对象?_C++_Templates_Static Polymorphism_Function Template - Fatal编程技术网

C++ 是否有一种通用方法将函数模板调整为多态函数对象?

C++ 是否有一种通用方法将函数模板调整为多态函数对象?,c++,templates,static-polymorphism,function-template,C++,Templates,Static Polymorphism,Function Template,例如,我有一些函数模板 template <typename T> void foo(T); template <typename T> void bar(T); // others 然后将其作为some_算法(foo_polymorphic())传递。但这需要为我的每个函数模板编写一个单独的适配器 是否有一种通用的方法将函数模板调整为多态函数对象,也就是说,我可以为我需要调整的每个函数模板重复使用某种机制,而不必为每个模板单独声明某些内容?为什么不能使用模板参数?

例如,我有一些函数模板

template <typename T>
void foo(T);

template <typename T>
void bar(T);

// others
然后将其作为
some_算法(foo_polymorphic())
传递。但这需要为我的每个函数模板编写一个单独的适配器


是否有一种通用的方法将函数模板调整为多态函数对象,也就是说,我可以为我需要调整的每个函数模板重复使用某种机制,而不必为每个模板单独声明某些内容?

为什么不能使用模板参数?你说你不能不经过论证就通过你的模板,但我不确定你以前是否听说过这个,如果听说过,告诉我,它不会起作用

我不知道你的代码结构是什么样子的,但是你能做一些类似的事情吗

我知道这是可行的,不知道这是否是你想要的:

template<typename T>
T some_algorithm(T data) { return T(); } // just returning nothing for example

template<typename T, T(*Something)(T)>
class FuncClass {
public:
    T run(T data) { return Something(data); }
};

template<typename T, typename Functor>
void apply_algorithm(T data) {
    Functor F;
    F.run(data);
}

int main() {
    int mydata = 4;
    apply_algorithm<int, FuncClass<int, some_algorithm<int> > >(mydata);

    cin.get();
}
模板
T一些_算法(T data){return T();}//例如,什么也不返回
模板
类函数类{
公众:
T运行(T数据){返回某物(数据);}
};
模板
无效应用_算法(T数据){
函子F;
F.运行(数据);
}
int main(){
int mydata=4;
应用_算法(mydata);
cin.get();
}

这个问题的简短版本被赋予了一个重载名称
f
,如何简洁地编写对象
ff
,从而
ff(a0,a1,a2,…)
最终调用
f(a0,a1,a2,…)

一个多态函子,你如何指出你自己,是通常的解决方案。但是它的定义必须是不一致的(因为它有一个模板成员),所以我认为这对于我的回答来说不够简洁

目前,lambda表达式产生一个单态函子,所以它们很接近,但不完全相同

// set of functions overloaded on int and double
void f(int);
void f(double);

auto ff = [](int i) { return f(i); };
正如GMan在评论中指出的,多态lambdas将(应该?)成为简洁地内联编写多态函子的解决方案

同时,可以编写一个
make_重载
helper,将多个函子组合成一个,这样

auto ff = make_overload(
    [](int arg0) { return f(arg0); }
    , [](double arg0) { return f(arg0); } );

将“捕获”整个过载集。也许Boost.Preprocessor宏可以在这里提供帮助,以便
auto ff=POLYMORPHIC_LAMBDA(1,(int)(double),{return f(arg0);}可以内联使用。然而,我怀疑存在算术限制(因此是第一个宏参数),这与通常的不合时宜的手写多态函子解决方案不同;因此这对变量函数模板没有帮助。

@Seth:因为这对语言没有意义。
非类型模板参数必须是整数、枚举、指针、引用或指向成员类型的指针,并且在编译时必须是常量。
不能传递非常量函数名,基本上是因为你找不到指向它的指针。你必须使用一些其他技巧。foo_多态性可以通过宏生成以简化任务。我要说的是,没有宏,这是不可能做到的。在C++0x中,如果存在多态lambda,您只需执行:
一些_算法([](autox){foo(x);})。从这一点来看,我认为您的问题与其他“如何模仿lambdas”的问题没有什么不同,只是在您的情况下,您需要更多增强的lambdas。与模拟兰博达斯的情况一样:手动:/我想指出的是,上面的结构可能有问题,因为它不是完美的将t转发到foo。如果
算法
是类类型,那就好了。函数不是。@GMan你能再看一次,看看它是否有意义吗?@GMan:这很有趣-函数模板可以绑定到任何东西吗?@Seth:你所做的就是指定实例化了哪些版本的
myalgo
(在本例中,
int
)。请注意,他的手动版本不需要知道任何东西,只需要知道函数名,因为演绎将处理其余部分。需要指定模板参数无法达到目的。我希望单函数模板稍微不太一般的情况可能比重载名称的一般情况更容易。我想不……有趣!如果我们能以某种方式获得函数需要调用的类型的
mpl::vector
,我们能写一个形式为
POLYMORPHIC_LAMBDA(f,mplvec)
?@HighCommander4的宏吗?它们有相似之处:名称
foo
(来自您的问题)不能作为函数参数传递(对于函数模板)或作为非类型模板参数,而不丢失多态性。这是问题的根源。@HighCommander4这是一个有趣的想法。但是,宏无法操作Boost.MPL序列;如果可以,则
from_sequence::make_重载()(f,f,f,f,f);
(假设这里有5个重载)这就是为什么在我的示例中使用Boost.PP序列的原因:宏必须插入名称(这是唯一表现为多态性的东西)的次数与重载的次数一样多。它仍然比我的插入一个整体的命题更复杂,并且它处理要启动的算术!(请注意,这种扩展的讨论在C++聊天中是受欢迎的)(LUC:我不同意,即使网站所有者不这样想。你的讨论完全属于这里,就在它开始的上下文中。这样读者们就不必去搜索一些聊天室,只发现它被删除了。)
// set of functions overloaded on int and double
void f(int);
void f(double);

auto ff = [](int i) { return f(i); };
auto ff = make_overload(
    [](int arg0) { return f(arg0); }
    , [](double arg0) { return f(arg0); } );