以函数指针作为参数的 C++ 外部函数,在带有成员函数的 class 内部使用
C++ External function with pointer to function as parameter, used inside a class with a member function
对 C++ 相当陌生。假设我有一个 class:
class A
{
private:
double m_x, m_y;
public:
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, *intF);
}
double intF(double x) { return 2*x; }
};
并且它使用了在别处定义的外部全局函数:
double extF(double x, double y, std::function<double(double)> f)
{
if (x*y < 0)
return f(x);
else
return f(y);
}
公式是假的。这不编译。我尝试了简单的 intF
、A::*intF
、&A::intF
,甚至一些非正统的组合,但这只是猜测。问题是 class A
不是唯一一个使用全局外部函数的函数,它应该是用户在运行时选择的东西。搜索显示了一些答案,说不可能像这样创建一个指向成员函数的指针,因为它需要实例化(?),但我没有找到解决方案。这可以做到吗?如果是,如何?
编辑:附加问题:如果成员函数是const double f(...) const
,如何指向成员函数的指针?
您可以使用std::bind
绑定成员函数。
A(double x, double y): m_x {x}
{
using namespace std::placeholders;
m_y = extF(m_x, y, std::bind(&A::intF, this, _1));
}
或使用 lambda.
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, [this](double d) { return intF(d); });
}
顺便说一句:它也适用于 const 成员函数,这在这里无关紧要。
一个变体就是使用 lambda:
class A
{
private:
double m_x, m_y;
public:
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, [&](double d){ return intF(d);});
}
double intF(double x) { return 2*x; }
};
另一种变体是使用 lambda 和 std::mem_fn
(省略 class 的其余代码):
A(double x, double y): m_x {x}
{
auto fn = std::mem_fn(&A::intF);
m_y = extF(m_x, y, [&](double d) {return fn(this, d);});
}
如果你 bind 成员函数指针的对象参数,最后你可能会摆脱 lambdas:
A(double x, double y): m_x {x}
{
auto fn1 = std::bind(std::mem_fn(&A::intF), this, std::placeholders::_1);
m_y = extF(m_x, y, fn1);
}
所有这些也适用于常量成员函数。
对 C++ 相当陌生。假设我有一个 class:
class A
{
private:
double m_x, m_y;
public:
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, *intF);
}
double intF(double x) { return 2*x; }
};
并且它使用了在别处定义的外部全局函数:
double extF(double x, double y, std::function<double(double)> f)
{
if (x*y < 0)
return f(x);
else
return f(y);
}
公式是假的。这不编译。我尝试了简单的 intF
、A::*intF
、&A::intF
,甚至一些非正统的组合,但这只是猜测。问题是 class A
不是唯一一个使用全局外部函数的函数,它应该是用户在运行时选择的东西。搜索显示了一些答案,说不可能像这样创建一个指向成员函数的指针,因为它需要实例化(?),但我没有找到解决方案。这可以做到吗?如果是,如何?
编辑:附加问题:如果成员函数是const double f(...) const
,如何指向成员函数的指针?
您可以使用std::bind
绑定成员函数。
A(double x, double y): m_x {x}
{
using namespace std::placeholders;
m_y = extF(m_x, y, std::bind(&A::intF, this, _1));
}
或使用 lambda.
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, [this](double d) { return intF(d); });
}
顺便说一句:它也适用于 const 成员函数,这在这里无关紧要。
一个变体就是使用 lambda:
class A
{
private:
double m_x, m_y;
public:
A(double x, double y): m_x {x}
{
m_y = extF(m_x, y, [&](double d){ return intF(d);});
}
double intF(double x) { return 2*x; }
};
另一种变体是使用 lambda 和 std::mem_fn
(省略 class 的其余代码):
A(double x, double y): m_x {x}
{
auto fn = std::mem_fn(&A::intF);
m_y = extF(m_x, y, [&](double d) {return fn(this, d);});
}
如果你 bind 成员函数指针的对象参数,最后你可能会摆脱 lambdas:
A(double x, double y): m_x {x}
{
auto fn1 = std::bind(std::mem_fn(&A::intF), this, std::placeholders::_1);
m_y = extF(m_x, y, fn1);
}
所有这些也适用于常量成员函数。