Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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 - Fatal编程技术网

C++ 将泛型方法的指针传递到模板类

C++ 将泛型方法的指针传递到模板类,c++,templates,C++,Templates,我想创建一个模板类,其构造函数接受一个对象指针和一个指向对象方法之一的指针。模板类必须接受带有任何参数的方法,因此我认为该方法的类型应该是模板参数。我也更愿意接受任何返回类型的方法,但将其约束为返回void也可以。下面的代码无法编译。正确的语法是什么 template <typename Obj, typename Method> class Foo { public: Foo(Obj *obj, Obj::*Method method) :mObj(obj), mMet

我想创建一个模板类,其构造函数接受一个对象指针和一个指向对象方法之一的指针。模板类必须接受带有任何参数的方法,因此我认为该方法的类型应该是模板参数。我也更愿意接受任何返回类型的方法,但将其约束为返回void也可以。下面的代码无法编译。正确的语法是什么

template <typename Obj, typename Method>
class Foo
{
public:
  Foo(Obj *obj, Obj::*Method method)
    :mObj(obj), mMethod(method)
  {}

  void callMethod()
  {
    mObj->mMethod();
  }

private:
  Obj* mObj;
  Obj::*Method mMethod;
};

class Bar
{
public:
  // I want it to work no matter what arguments this method takes.
  void method() {}
};

Bar bar;
Foo <Bar, void(Bar::*)()> foo(&bar, &Bar::method);
模板
福班
{
公众:
Foo(Obj*Obj,Obj::*方法)
:mObj(obj),M方法(方法)
{}
void callMethod()
{
mObj->mMethod();
}
私人:
Obj*mObj;
目标::*方法M方法;
};
分类栏
{
公众:
//我希望无论这个方法采用什么参数,它都能工作。
void方法(){}
};
酒吧;
Foo-Foo(&bar,&bar::方法);
我在Foo构造函数中遇到以下错误:

error C2059: syntax error: '<tag>::*'
错误C2059:语法错误:'::*'

我对这个主题的描述被标记为重复,但是引用的示例指定了可以传递的方法的确切类型,我需要它是泛型的。

首先,代码中有几个语法问题。另外,您根本不需要将
方法
作为模板参数,因为您总是希望传递
对象
类型的成员函数

要在
callMethod
中获得可变数量的参数,只需向
Foo
提供可变参数包即可。此外,还可以推断
callMethod
函数的返回类型

将所有这些放在一起,您可以得到:

template <typename Obj, typename Ret, typename ...Args>
class Foo
{
public:
  Foo(Obj *obj, Ret (Obj::*method)(Args...))
    : mObj(obj), mMethod(method)
  {}

  Ret callMethod(Args... args)
  {
    return (mObj->*mMethod)(args...);
  }

private:
  Obj* mObj;
  Ret (Obj::*mMethod)(Args...);  // this is essentially 'Method'
};

首先,代码中有几个语法问题。另外,您根本不需要将
方法
作为模板参数,因为您总是希望传递
对象
类型的成员函数

要在
callMethod
中获得可变数量的参数,只需向
Foo
提供可变参数包即可。此外,还可以推断
callMethod
函数的返回类型

将所有这些放在一起,您可以得到:

template <typename Obj, typename Ret, typename ...Args>
class Foo
{
public:
  Foo(Obj *obj, Ret (Obj::*method)(Args...))
    : mObj(obj), mMethod(method)
  {}

  Ret callMethod(Args... args)
  {
    return (mObj->*mMethod)(args...);
  }

private:
  Obj* mObj;
  Ret (Obj::*mMethod)(Args...);  // this is essentially 'Method'
};

只是一点语法错误:
methodobj::*方法
。为什么不直接使用
std::function
和/或
std::bind
?什么是
?@idclev463035818 MSVC的解析器变得混乱并抛出一个通用错误字符串。只是一点语法错误:
方法Obj:*方法
。为什么不直接使用它呢
std::function
和/或
std::bind
?什么是
?@idclev463035818 MSVC的解析器变得混乱,并吐出一个通用错误字符串。您的可变版本与另一个版本等效(
方法
只是
无效(int,double)
),但是您现在已经失去了处理非
void
成员函数的能力。Edit:嗯,不是等效的,但你明白我的意思了:一个
ReturnType
参数就好了。嗯,似乎OP可以使用void return type,但这两种方法都可以:)@cigien在我的编译器(Visual Studio 2015)上,它在声明Foo对象时需要模板参数。你怎么能省略它们——这是gcc的东西吗?你需要c++17。在此之前,没有类模板参数推断。为答案添加了修复程序。@cigien这对于C++11会是什么样子?您的变量版本与另一个版本相当(
Method
只是
void(int,double)
),但您现在已经失去了处理非
void
成员函数的能力。Edit:嗯,不是等效的,但你明白我的意思了:一个
ReturnType
参数就好了。嗯,似乎OP可以使用void return type,但这两种方法都可以:)@cigien在我的编译器(Visual Studio 2015)上,它在声明Foo对象时需要模板参数。你怎么能省略它们——这是gcc的东西吗?你需要c++17。在此之前,没有类模板参数推断。为答案添加了修复。@cigien这对于C++11会是什么样子?
Foo <Bar, void> a(&bar, &Bar::method);
Foo <Car, int, int, double> b(&car, &Car::method2);