0

假设我们有一个包含 n 个变量的函数

y = f (x1, ..., xn) 

我想将这样的函数作为参数传递。

在 Matlab 中,可以使用以下使用句柄的构造:

function y=func(x)
y = sin(x(0)) * cos(x(1))  //Any definition, not important

p_func=@func; //Define handle

可以将句柄用作另一个函数的参数:

y = function2(p_func, n);

其中n代表一个维度...

如何使用 C++ 重写此代码?我们使用带有函数模板的简单模型

temmplate <typename T>
T func( const T *arg, const short n) {return sin(arg[0]) * cos(arg[1])};

其中 xi 参数由 n 个元素的一维数组表示。问题是在这种情况下不能使用指向函数模板的指针

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

只是一个专业化...也许其他模型可能更合适...谢谢您的帮助...

备注: 我知道类模板很有用

template  <typename T>
class Foo
{ 
    T func( const T *args, const short n);
};

这个建筑工程:

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

但它可能不会在库的当前模型中使用(我不能影响这一点)。

4

4 回答 4

3

C++ 是一种静态类型语言。C++ 中的每个对象,无论是函数指针还是其他任何对象,都必须具有特定的类型。并且函数指针的类型基于给定要指向的函数的参数类型。

模板不是对象,因此您无法获得指向模板的指针。您可以获得指向模板实例化的指针。使用您的func定义,func<int>是一个接受 aconst int*和 a的函数short。您可以获得指向func<int>. 但是func是模板;您无法获得指向模板的指针。

这就是为什么 C++ 程序经常抛出仿函数而不是函数指针的原因。Functor 可以有一个模板operator()方法,因此您可以像在传递模板函数一样调用它们。但是既然你说你必须使用一个函数指针,那就没有什么可以做的了。

于 2012-10-01T19:31:47.943 回答
1

我认为这在 C++ 中不容易解决,但有类似情况的方法。你应该看看boost::bind 和 boost::function库。它是为绕过在 C++ 中传递函数指针的讨厌细节而设计的(它们也允许传递类方法)。据我记得,他们并没有真正使用通用的 N 而是为任意 N 参数实例化模板。如果您想获得类似的东西,绝对值得一看。

于 2012-10-01T19:30:52.343 回答
1

问题不在于“n”。问题是模板化类型 T。

您是否尝试在这里声明一个变量(类型为函数指针)?

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

如果不实例化模板,这将不起作用。

这是因为否则,类型检查将是不可能的。类型检查器无法检查初始化指针时 T 是否与取消引用时相同。

您可能需要查看更大的上下文。您想在哪里使用该声明?将模板参数移动到该上下文。

例如,您可以有一个带有模板参数 T 的函数或类。在那里,您可以声明、初始化和取消引用任何在其类型中某处具有 T 的函数指针。

也许您可以在分配函数指针的位置“绑定”参数。因此生成的函数将是一个空函数,您可以在不知道参数类型的情况下使用它。

于 2012-10-01T19:44:43.950 回答
1

您无法获得指向模板函数的指针,因为模板不是对象,它只是编译时语法构造,产生多个特定函数 -模板实例化。模板实例化,例如f<int>(const int*, short)是对象并且可以被指向。

如果您只是想要一些简单统一的方式从模板实例化中获取函数指针,请使用declspec()(我假设您使用的是现代 C++11 兼容编译器):

template <class T> static T f(const T *, const short )
{
  // Implementation
  ...
}

// Declaring function pointers for int & double
typedef decltype(&f<int>) IntFuncPtr;
typedef decltype(&f<double>) DoubleFuncPtr;

// Sample usage
IntFuncPtr intFunc = &f<int>;
intFunc(NULL, 0);

DoubleFuncPtr doubleFunc = &f<double>;
doubleFunc(NULL, 0);
于 2012-10-01T19:55:37.090 回答