- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个具有不同参数和返回类型的函数映射。所以,为了做到这一点,我通过 stackoverflow 进行了很多搜索,我想我得到了我需要的东西,但不完全是......
背景:
来自 this帖子,答案来自pmr是我需要的最准确的解决方案。因此,我已将函数 call 扩展为可变参数模板(我希望如此)。所以,这是我的调用版本(AnyCaller 类的其余部分完全相同):
template<typename Ret, typename ...Args>
Ret call(const std::string& s, Args&&... arg) {
// we have to assume that our users know what we are actually returning here
const boost::any& a = calls[s];
return boost::any_cast< std::function<Ret(Args...)> >(a)(std::forward<Args>(arg)...);
}
它编译正常。现在,这些是我用来测试该类的三个函数:
int foo() { MessageBoxW(nullptr, L"Helolo VOID", L"Info", NULL); return 1; }
double foo2(std::wstring str) { MessageBoxW(nullptr, str.data(), L"Info", NULL); return double(4.5); }
UINT foo3(std::wstring str1, std::wstring str2)
{
std::wstring strBuffer;
strBuffer = str1;
strBuffer += L"==>";
strBuffer += str2;
MessageBoxW(nullptr, strBuffer.data(), L"Info", NULL);
return 4;
}
因此,第一个的签名为 int(void),第二个 double(std::wstring) 和第三个 double(std: :wstring, std::wstring).
现在,这是测试代码:
AnyCaller c;
c.add("foo1", std::function<int(void)>(foo));
c.add("foo2", std::function<double(std::wstring)>(foo2));
c.add("foo3", std::function<UINT(std::wstring, std::wstring)>(foo3));
c.call<int>("foo1");
c.call<double, std::wstring>("foo2", std::wstring(L"foo2!!!").data());
c.call<UINT, std::wstring, std::wstring>("foo3", std::wstring(L"foo3!!!").data(), std::wstring(L"---foo3!!!").data());
一切顺利:)
所以,虽然这工作正常,但我真正需要的是添加对函数成员的支持。基本上,我所做的是创建一个 A 类,它具有完全相同的三个函数和一些用于测试目的的函数:
class A
{
public:
int foo() { MessageBoxW(nullptr, L"Helolo VOID", L"Info", NULL); return 1; }
double foo2(std::wstring str) { MessageBoxW(nullptr, str.data(), L"Info", NULL); return double(4.5); }
UINT foo3(std::wstring str1, std::wstring str2)
{
std::wstring strBuffer;
strBuffer = str1;
strBuffer += L"==>";
strBuffer += str2;
MessageBoxW(nullptr, strBuffer.data(), L"Info", NULL);
return 4;
}
std::wstring foo4(VOID) { return std::wstring(L"foo4"); }
std::wstring foo5(std::wstring strData) { return (strData + L"--foo5"); }
VOID foo6(VOID) { ; }
};
但是我无法让它工作。我的第一个问题是添加指向成员函数的指针:
A a;
c.add("foo1", std::function<int(void)>(&A::foo)); // => Not valid
c.add("foo1", std::function<int(void)>(&a.foo)); // => Not valid
c.add("foo1", &a.foo); // => Not valid
c.add("foo1", a.foo); // => Not valid
c.add("foo1", ?????); //What in heaven goes here?
显然一定是 a 的某种转换,但我无法想象是什么......
当然,在那之后,我需要做实际的调用:
int nRet = c.call<int>("foo1");
感谢任何可以提供帮助的人:_)
PS:我不能做静态成员,如果这是一个解决方案...
PS2:我正在使用 VS2013...
解决方案:
感谢@Kiroxas、@Praetorian 和 this 的评论帖子,我提出了一个不涉及可变参数模板的解决方案。
这些是我的测试类 A
和 B
:
class A
{
public:
int foo1() { MessageBoxW(nullptr, L"Helolo VOID", L"Info", NULL); return 1; }
int foo2(std::wstring str) { MessageBoxW(nullptr, str.data(), L"Info", NULL); return 5; }
int foo3(std::wstring str1, std::wstring str2)
{
std::wstring strBuffer;
strBuffer = str1;
strBuffer += L"==>";
strBuffer += str2;
MessageBoxW(nullptr, strBuffer.data(), L"Info", NULL);
return 4;
}
};
class B
{
public:
std::wstring foo4(VOID) { return std::wstring(L"foo4"); }
std::wstring foo5(std::wstring strData) { return (strData + L"--foo5"); }
VOID foo6(VOID) { ; }
double foo7(std::wstring str1, int nNum)
{
std::wstring strBuffer;
strBuffer = str1;
strBuffer += L"==>";
strBuffer += std::to_wstring(nNum);
MessageBoxW(nullptr, strBuffer.data(), L"Info", NULL);
return double(3.1415);
}
};
这是将它们插入数组并调用它们的代码 :) 我理想的解决方案是将它们插入 map ,所以,一旦我完成所有工作,我将再次更新 ¡帖子。
typedef struct
{
UINT ID;
std::wstring NAME;
boost::any Func;
} funcs;
funcs CallBackItems[] =
{
//From class A
{ 0, L"foo1", std::function<int(void)>(std::bind(&A::foo1, a)) },
{ 1, L"foo2", std::function<int(std::wstring)>(std::bind(&A::foo2, a, std::placeholders::_1)) },
{ 2, L"foo3", std::function<int(std::wstring, std::wstring)>(std::bind(&A::foo3, a, std::placeholders::_1, std::placeholders::_2)) },
//From class B
{ 3, L"foo4", std::function<std::wstring(void)>(std::bind(&B::foo4, b)) },
{ 4, L"foo5", std::function<std::wstring(std::wstring)>(std::bind(&B::foo5, b, std::placeholders::_1)) },
{ 5, L"foo6", std::function<void(void)>(std::bind(&B::foo6, b)) },
{ 6, L"foo7", std::function<double(std::wstring, int)>(std::bind(&B::foo7, b, std::placeholders::_1, std::placeholders::_2)) }
};
int nResult = -1;
std::wstring wstrResult = L"";
double dResult = 0.0;
//class A
nResult = boost::any_cast<std::function<int(void)>>(CallBackItems[0].Func)();
nResult = boost::any_cast<std::function<int(std::wstring)>>(CallBackItems[1].Func)(L"foo2");
nResult = boost::any_cast<std::function<int(std::wstring, std::wstring)>>(CallBackItems[2].Func)(L"foo", L"3");
//class B
wstrResult = boost::any_cast<std::function<std::wstring(void)>>(CallBackItems[3].Func)();
wstrResult = boost::any_cast<std::function<std::wstring(std::wstring)>>(CallBackItems[4].Func)(L"foo5");
boost::any_cast<std::function<void(void)>>(CallBackItems[5].Func)();
dResult = boost::any_cast<std::function<double(std::wstring, int)>>(CallBackItems[6].Func)(L"foo", 7);
最佳答案
A::foo(1|2|3)
是非静态成员函数,这意味着它们采用隐式第一个参数,指向调用它们的对象实例的指针(this
指针)。您有两个选项可用,要么使用 std::bind
绑定(bind)您要在其上调用成员函数的对象,要么稍后在您 call( )
它。
我正在用一个可变参数模板版本替换你的两个 call
重载
template<typename Ret, typename... T>
Ret call(const std::string& s, T&&... arg) {
// we have to assume that our users know what we are actually returning here
const boost::any& a = calls[s];
return boost::any_cast< std::function<Ret(T...)> >(a)(std::forward<T>(arg)...);
}
选项 1:使用 std::bind
A a;
AnyCaller c;
c.add("foo1", std::function<int()>(std::bind(&A::foo1, &a)));
c.add("foo2", std::function<double(std::wstring)>(
std::bind(&A::foo2, &a, std::placeholders::_1)));
c.call<int>("foo1");
c.call<double>("foo2", std::wstring(L"Calling foo2"));
选项2:调用函数时传递对象指针。请注意,在这种情况下,std::function
的类型不同。
A a;
AnyCaller c;
c.add("foo1", std::function<int(A*)>(&A::foo1));
c.add("foo2", std::function<double(A*, std::wstring)>(&A::foo2));
c.call<int>("foo1", &a);
c.call<double>("foo2", &a, std::wstring(L"Calling foo2"));
第二个选项does not work在 VS2013 上。
Live demo两种选择。
关于c++ - 从指向 boost::any 的指针调用可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24558070/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!