没有指定第一个参数的可变参数函数? [英] Variadic function without specified first parameter?
问题描述
出于好奇,我想我会尝试编写一个模仿C#的多委托模式的基本C ++类.下面的代码主要完成了这项工作,但是却牺牲了几乎所有的类型安全性,但是不得不使用初始的哑参数来设置va_list确实有点麻烦.没有这种方法,有没有办法使用va_list?我确实意识到有很多方法可以(例如)使用boost来做到这一点,但是我的目标是只使用标准库的简单的东西.
Out of curiosity, I thought I'd try and write a basic C++ class that mimics C#'s multiple delegate pattern. The code below mostly does the job, with the nasty sacrifice of losing almost all type-safety, but having to use the initial dummy parameter to set up the va_list really seems a bit off. Is there a way to use va_list without this? I do realize there are ways to do this with (for example) boost, but I was aiming for something dead simple that used just the standard library.
#include <vector>
#include <iostream>
#include <string>
#include <stdarg.h>
#include <algorithm>
using namespace std;
class CDelegate
{
public:
virtual bool operator()(va_list params) = 0;
};
class CMultipleDelegateCaller
{
public:
typedef vector<CDelegate*> CDelegateVector;
CMultipleDelegateCaller& operator+=(CDelegate &rDelegate)
{
m_apDelegates.push_back(&rDelegate);
return (*this);
}
CMultipleDelegateCaller& operator-=(CDelegate &rDelegate)
{
CDelegateVector::iterator iter =
find(m_apDelegates.begin(), m_apDelegates.end(), &rDelegate);
if (m_apDelegates.end() != iter) m_apDelegates.erase(iter);
return (*this);
}
bool Call(int iDummy, ...)
{
va_list params;
CDelegate* pDelegate;
CDelegateVector::iterator iter;
for (iter = m_apDelegates.begin(); iter != m_apDelegates.end(); ++iter)
{
pDelegate = *iter;
va_start(params, iDummy);
if (!(*pDelegate)(params)) return false;
va_end(params);
}
return true;
}
private:
CDelegateVector m_apDelegates;
};
class CTestDelegate:
public CDelegate
{
public:
CTestDelegate():m_iId(++s_iCount) {}
virtual bool operator()(va_list params)
{
int iIntParam = va_arg(params, int);
char* szCharPtrParam = va_arg(params, char*);
string* psStringParam = va_arg(params, string*);
cout<<m_iId<<"{"
<<iIntParam<<", "
<<szCharPtrParam<<", "
<<*psStringParam<<"}"<<endl;
return true;
}
int m_iId;
static int s_iCount;
};
int CTestDelegate::s_iCount = 0;
int main(int argc, char* argv[])
{
CMultipleDelegateCaller cDelegateCaller;
CTestDelegate cTestDelegate1;
CTestDelegate cTestDelegate2;
cout<<"--------------------"<<endl;
cDelegateCaller += cTestDelegate1;
cDelegateCaller += cTestDelegate2;
string sString("World");
cDelegateCaller.Call(1, 2, "Hello", &sString);
cout<<"--------------------"<<endl;
cDelegateCaller -= cTestDelegate1;
cDelegateCaller.Call(1, 2, "Hello", &sString);
cout<<"--------------------"<<endl;
cDelegateCaller -= cTestDelegate2;
cDelegateCaller.Call(1, 2, "Hello", &sString);
cout<<"--------------------"<<endl;
cin>>sString;
return 0;
}
推荐答案
C ++中带有省略号的功能仅是为了与C兼容.使用C ++时,我将在 Call
函数中返回临时帮助对象并添加模板 operator%
传递可变数量的参数.要通过以下方式使用它:
Functions with ellipsis in C++ is only for compatibility with C. Using C++ I'd return temporary helper object in Call
function and add template operator%
to pass variable number of arguments. To use it in the following way:
cDelegateCaller.Call() % 2 % "Hello" % sString; // dummy argument isn't required
对于您的问题,Standard要求在访问未命名参数之前调用 va_start
.而 va_start
需要第二个参数,它是函数定义中变量参数列表中最右边的参数的标识符.
As to your question, Standard requires to invoke va_start
before any access to the unnamed arguments. And va_start
requires second argument which is the identifier of the rightmost parameter in the variable parameter list in the function definition.
这篇关于没有指定第一个参数的可变参数函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!