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
将指向模板函数的指针作为函数参数传递? < P>我想在两个输入上执行C++函数,把它们当作给定的类型:_C++_Templates_Operator Overloading - Fatal编程技术网

将指向模板函数的指针作为函数参数传递? < 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; });