class 方法的函数对象
function objects for class methods
我知道当函数不是方法时如何使函数成为输入参数,但当函数是时我不知道如何做方法。
这是我尝试过的:
#include <iostream>
class A
{
void funct_1(int a, void (A::*f)(int))
{
(A::*f)(a);
}
public:
void funct_2(int k)
{
// do something
}
void funct_3(int k)
{
// do something
}
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, funct_2);
else
funct_1(k, funct_3);
}
};
int main()
{
A a;
a.funct_4(4);
return 0;
}
以上代码无法编译。我尝试了很多变体,但找不到任何有效的语法用法。
有人可以根据语法解释我在这里做错了什么吗?
指向成员语法的指针总是很难弄清楚。你一直都在,只要把第一个成员函数改成
void funct_1(int a, void (A::*f)(int))
{
(this->*f)(a);
}
和第四到
void funct_4(int k)
{
if (k % 2)
funct_1(k, &A::funct_2);
else
funct_1(k, &A::funct_3);
}
对于您最初尝试调用成员函数的尝试,请注意 (A::*f)(a);
在概念上是错误的,因为它没有将成员函数指针 f
与 实例相关联 共 A
。成员函数指针是 class 定义中的偏移量,但并不紧贴 class 的特定实例。这必须在进行实际调用时提供。存在特定的运算符来执行此操作,即 .*
和 ->*
,如 this->*f
。由于它们的优先级较低,您需要添加一组额外的括号:(this->*f)
.
我不知道你是否需要使用精确的签名,但你不能这样做吗?
template<typename Func>
void funct_1(int a, Func&& func)
{
std::forward<Func>(func)(a);
}
您的方法的签名没有改变:
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, funct_2);
else
funct_1(k, funct_3);
}
您甚至可以为任意数量的参数扩展它
template<typename Func>
void funct_1(Func&& func, Args&&... args)
{
std::forward<Func>(func)(std::forward<Args>(args)...);
}
那些允许使用函数作为参数。如果您打算按照您展示的方式在 class 中使用它,它主要是 design-flaw 和 re-think class 结构。
如果您想在 class 中传递成员函数,请将其包含在 lambda 和 std::function 中,因此您可以将其用作变量并使用上述方法。
如果您只是想为您的示例提供一种干净的方式,实际上确实存在一种极端方式:
void funct_1(int a, auto&& func)
{
(this->*func)(a);
}
所以你的样本变成了
#include <iostream>
#include <functional>
class A
{
void funct_1(int a, auto&& func)
{
(this->*func)(a);
}
public:
void funct_2(int k)
{
std::cout << "func 2" << std::endl;
}
void funct_3(int k)
{
std::cout << "func 3" << std::endl;
}
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, &A::funct_2);
else
funct_1(k, &A::funct_3);
}
};
int main()
{
A a;
a.funct_4(4);
return 0;
}
我知道当函数不是方法时如何使函数成为输入参数,但当函数是时我不知道如何做方法。
这是我尝试过的:
#include <iostream>
class A
{
void funct_1(int a, void (A::*f)(int))
{
(A::*f)(a);
}
public:
void funct_2(int k)
{
// do something
}
void funct_3(int k)
{
// do something
}
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, funct_2);
else
funct_1(k, funct_3);
}
};
int main()
{
A a;
a.funct_4(4);
return 0;
}
以上代码无法编译。我尝试了很多变体,但找不到任何有效的语法用法。 有人可以根据语法解释我在这里做错了什么吗?
指向成员语法的指针总是很难弄清楚。你一直都在,只要把第一个成员函数改成
void funct_1(int a, void (A::*f)(int))
{
(this->*f)(a);
}
和第四到
void funct_4(int k)
{
if (k % 2)
funct_1(k, &A::funct_2);
else
funct_1(k, &A::funct_3);
}
对于您最初尝试调用成员函数的尝试,请注意 (A::*f)(a);
在概念上是错误的,因为它没有将成员函数指针 f
与 实例相关联 共 A
。成员函数指针是 class 定义中的偏移量,但并不紧贴 class 的特定实例。这必须在进行实际调用时提供。存在特定的运算符来执行此操作,即 .*
和 ->*
,如 this->*f
。由于它们的优先级较低,您需要添加一组额外的括号:(this->*f)
.
我不知道你是否需要使用精确的签名,但你不能这样做吗?
template<typename Func>
void funct_1(int a, Func&& func)
{
std::forward<Func>(func)(a);
}
您的方法的签名没有改变:
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, funct_2);
else
funct_1(k, funct_3);
}
您甚至可以为任意数量的参数扩展它
template<typename Func>
void funct_1(Func&& func, Args&&... args)
{
std::forward<Func>(func)(std::forward<Args>(args)...);
}
那些允许使用函数作为参数。如果您打算按照您展示的方式在 class 中使用它,它主要是 design-flaw 和 re-think class 结构。
如果您想在 class 中传递成员函数,请将其包含在 lambda 和 std::function 中,因此您可以将其用作变量并使用上述方法。
如果您只是想为您的示例提供一种干净的方式,实际上确实存在一种极端方式:
void funct_1(int a, auto&& func)
{
(this->*func)(a);
}
所以你的样本变成了
#include <iostream>
#include <functional>
class A
{
void funct_1(int a, auto&& func)
{
(this->*func)(a);
}
public:
void funct_2(int k)
{
std::cout << "func 2" << std::endl;
}
void funct_3(int k)
{
std::cout << "func 3" << std::endl;
}
void funct_4(int k)
{
// some reason to use the function argument functionality...
if (k % 2)
funct_1(k, &A::funct_2);
else
funct_1(k, &A::funct_3);
}
};
int main()
{
A a;
a.funct_4(4);
return 0;
}