将指向模板函数的指针作为函数参数传递? < P>我想在两个输入上执行C++函数,把它们当作给定的类型:
伪:将指向模板函数的指针作为函数参数传递? < P>我想在两个输入上执行C++函数,把它们当作给定的类型:,c++,templates,operator-overloading,C++,Templates,Operator Overloading,伪: function(var X,var Y,function OP) { if(something) return OP<int>(X,Y); else if(something else) return OP<double>(X,Y); else return OP<string>(X,Y); } 函数(变量X、变量Y、函数OP) { 如果(某物) 返回OP(X,Y); 如果(其他事情) 返回OP(X,Y); 其他的 返回OP(X,Y
function(var X,var Y,function OP)
{
if(something)
return OP<int>(X,Y);
else if(something else)
return OP<double>(X,Y);
else
return OP<string>(X,Y);
}
函数(变量X、变量Y、函数OP)
{
如果(某物)
返回OP(X,Y);
如果(其他事情)
返回OP(X,Y);
其他的
返回OP(X,Y);
}
适合OP的函数可能如下所示:
template <class T> add(var X,var Y)
{
return (T)X + (T)Y; //X, Y are of a type with overloaded operators
}
模板添加(变量X,变量Y)
{
return(T)X+(T)Y;//X,Y属于重载运算符的类型
}
那么,问题是函数的签名是什么样的?如果运算符函数是非模板化的,我可以这样做,但我对这种额外的复杂性感到困惑。你在找这个吗
template<class T> T add(T X, T Y)
{
return X + Y;
}
模板T添加(T X,T Y)
{
返回X+Y;
}
或者你在找一种叫做add的东西
template<class T, class F>
T Apply(T x, T y, F f)
{
return f( x, y );
}
模板
T应用(tx,tyf)
{
返回f(x,y);
}
致电:
int x = Apply( 2, 4, add<int> );
intx=Apply(2,4,add);
我有点困惑……为什么要在伪代码中进行类型区分
C++模板允许对模板进行完全类型推断:
template <typename T, typename F>
T function(T x, T y, F op) {
return op(x, y);
}
模板
T函数(tx,tyf,op){
返回op(x,y);
}
在这里,
F
适合任何可能使用()
函数调用语法调用的函数(尤其是函数),并且只接受两个类型为T
(或隐式转换为它)的参数。我想您正在寻找答案。我不确定您问题中的var
是什么意思。它当然不是一个有效的C++关键字,所以我假设它是一个类似于<代码> Boost的类型:任何< /COD>。此外,函数缺少结果类型。我添加了另一个var
,不管是什么。您的解决方案可能如下所示:
template< template<typename> class Func >
var function(var X, var Y, Func OP)
{
if(something)
return OP<int>(X,Y);
else if(something else)
return OP<double>(X,Y);
else
return OP<string>(X,Y);
}
模板函数不能作为模板参数传递。在将此函数传递给另一个模板函数之前,必须手动推导出该函数的模板参数。例如,你有一个函数
T sum(T a, T b)
{
return a + b;
}
要将其传递给callFunc:
template<typename F, typename T>
T callFunc(T a, T b, F f)
{
return f(a, b);
}
你必须写作
int a = callFunc(1, 2, sum<int>);
inta=callFunc(1,2,和);
为了能够在不写入int的情况下传递sum,您必须使用操作符()编写一个functor-struct或类来调用模板函数。然后可以将此函子作为模板参数传递。这里有一个例子
template<class T>
T sum(T a, T b)
{
return a + b;
}
template<class T>
struct Summator
{
T operator()(T a, T b)
{
return sum<T>(a, b);
}
};
template<template<typename> class TFunctor, class T>
T doSomething(T a, T b)
{
return TFunctor<T>()(a, b);
//Equivalent to this:
//TFunctor<T> functor;
//return functor(a, b);
}
int main()
{
int n1 = 1;
int n2 = 2;
int n3 = doSomething<Summator>(n1, n2); //n3 == 3
return 0;
}
模板
T总和(T a,T b)
{
返回a+b;
}
模板
结构求和器
{
T运算符()(T a,T b)
{
回报金额(a、b);
}
};
模板
剂量测定法(TA,TB)
{
返回TFunctor()(a,b);
//相当于:
//函数函子;
//返回函子(a,b);
}
int main()
{
int n1=1;
int n2=2;
int n3=doSomething(n1,n2);//n3==3
返回0;
}
我使用lambdas进行此操作
auto add = [](const auto& lhs, const auto& rhs) {
static_assert(std::is_arithmetic<typename std::decay<decltype(lhs)>::type>::value,
"Needs to be arithmetic.");
static_assert(std::is_arithmetic<typename std::decay<decltype(rhs)>::type>::value,
"Needs to be arithmetic.");
return lhs + rhs;
};
template<typename LHS, typename RHS, typename FUNC
, typename OUT = typename std::result_of<FUNC(LHS, RHS)>::type>
constexpr OUT do_arithmetic(LHS lhs, RHS rhs, FUNC func) {
return func(lhs, rhs);
}
constexpr auto t = do_arithmetic(40, 2, add);
static_assert(t == 42, "Wrong answer!");
static_assert(std::is_same<std::decay<decltype(t)>::type, int>::value,
"Should be int.");
auto add=[](常量自动和左侧、常量自动和右侧){
静态_断言(std::is_算术::值,
“需要算术。”);
静态_断言(std::is_算术::值,
“需要算术。”);
返回左侧+右侧;
};
模板
constexpr OUT do_算术(左S左S右S,右S右S,FUNC FUNC){
返回函数(左、右);
}
constexpr auto t=do_算术(40,2,add);
静态断言(t==42,“回答错误!”);
静态断言(std::is_same::value,
“应为int.”;
模板作废功能(OP)
{
//用int调用
op(1,2);
//还是双份的
op(1.2,2.3);
//使用显式模板参数调用
op.template操作符()(1,2);
op.template运算符()(“一”、“二”);
}
结构添加
{
模板T运算符()(TA,TB)
{
返回a+b;
}
};
函数(Add());
//或者使用C++14 lambda调用
函数([](自动a,自动b){返回a+b;});
查看模板参数。(这不是打字错误。)+1,这基本上是正确的答案如何通过OP。我添加了这个作为答案。我希望我没有在其中加入任何愚蠢的错误。我想这就是我的意思,没有将函数视为模板参数。唯一的问题是F不能是具有未知模板参数的模板函数,它也必须是非模板函数,或指定了所有模板类型的模板函数。@izogfif还可以显式指定模板参数。可以使用模板元编程来推导它们。但是无论如何,这似乎是回答了OP的问题,不必再复杂化。Visual C++ 2008,Visual C++ 2010由于编译错误而不能工作。@ IZOFIF:现在成像,你已经提供了确切的编译器错误。可能有人来过,看了看,明白了问题所在,并发布了解决方案。当然,我们不想要这个,所以你没有提供这个很好。很好。下面是我试图编译的代码和编译器(在代码末尾)提出的错误:我相信他希望在不指定int作为模板参数的情况下通过add。如果人们使用正确的术语:“模板函数”不存在,它们是“函数模板”,那么这种混淆就不会出现。也就是说,在您的示例中callFunc(1,2,sum)
您没有将函数传递给callFunc
,而是将模板传递给它(正如您的示例所示,您可以将模板作为模板参数传递,但只能传递类模板,不能传递函数模板)。Hm。。我不是这么想的。我认为最初的问题应该是“如何将函数模板作为函数模板参数传递”,对吗?那么,如果sum是类的非静态成员,您将如何使此解决方案工作?这绝对是一个极好的方法。我要做的唯一改进是使该方法保持静态。例如,调用方法run
。这将允许您避免每次调用sum
code时都必须创建一个新的类实例。您甚至可以将模板从类移动到操作符()
,这样您就有了一个带有模板T操作符()(ta,tb)
的常规类求和器。然后您可以使用常规模板进行doSomething
inste
template<class T>
T sum(T a, T b)
{
return a + b;
}
template<class T>
struct Summator
{
T operator()(T a, T b)
{
return sum<T>(a, b);
}
};
template<template<typename> class TFunctor, class T>
T doSomething(T a, T b)
{
return TFunctor<T>()(a, b);
//Equivalent to this:
//TFunctor<T> functor;
//return functor(a, b);
}
int main()
{
int n1 = 1;
int n2 = 2;
int n3 = doSomething<Summator>(n1, n2); //n3 == 3
return 0;
}
auto add = [](const auto& lhs, const auto& rhs) {
static_assert(std::is_arithmetic<typename std::decay<decltype(lhs)>::type>::value,
"Needs to be arithmetic.");
static_assert(std::is_arithmetic<typename std::decay<decltype(rhs)>::type>::value,
"Needs to be arithmetic.");
return lhs + rhs;
};
template<typename LHS, typename RHS, typename FUNC
, typename OUT = typename std::result_of<FUNC(LHS, RHS)>::type>
constexpr OUT do_arithmetic(LHS lhs, RHS rhs, FUNC func) {
return func(lhs, rhs);
}
constexpr auto t = do_arithmetic(40, 2, add);
static_assert(t == 42, "Wrong answer!");
static_assert(std::is_same<std::decay<decltype(t)>::type, int>::value,
"Should be int.");
template <class OP> void function(OP op)
{
// call with int
op(1, 2);
// or with double
op(1.2, 2.3);
// call with explicit template argument
op.template operator()<int>(1, 2);
op.template operator()<string>("one", "two");
}
struct Add
{
template <class T> T operator ()(T a, T b)
{
return a + b;
}
};
function(Add());
// or call with C++14 lambda
function([](auto a, auto b) { return a + b; });