好吧,我在这方面取得了一些进展。如果我使用Boost::Any数组,我可以将其转换为void*,也可以从void*转换为void*(因此,可以将它作为自定义窗口消息中的lparam传递给msgproc)。解决方案是,如果发送方类和接收方类都具有相同的模板参数。也就是说,类似这样的东西(应该在2010年编译为一个控制台项目):
#include <boost\any.hpp>
#include <vector>
#include <iostream>
#include <string>
// A class to receive the event.
template<typename A0 = int, typename A1 = int, typename A2 = int>
class A
{
public:
void Go()
{
std::wcout << L"(0 params)\n";
}
void Go(A0 u0)
{
std::wcout << L"1 param " << u0 << L"\n";
}
void Go(A0 u0, A1 u1)
{
std::wcout << L"2 params " << u0 << L" " << u1 << L"\n";
}
void Go(A0 u0, A1 u1, A2 u2)
{
std::wcout << L"3 params " << u0 << L" " << u1 << L" " << u2 << L"\n";
}
};
// A class to demonstrate passing an abitrary object.
class B
{
public:
};
// Implement operator on type B so we can use std::cout.
std::wostream& operator << (std::wostream& o, const B& b)
{
o << L"Hello!";
return o;
}
// A class that converts an array of boost::any from void and calls an appropriate function on A.
template<typename A0 = int, typename A1 = int, typename A2 = int>
class C
{
public:
void Everything()
{
// Create a collection of variants.
std::vector<boost::any> myVariants;
B myB;
myVariants.push_back(123);
myVariants.push_back(myB);
// Take a void pointer to them.
void *variants = &myVariants;
// Convert back into an array.
std::vector<boost::any>& myConverted = *(std::vector<boost::any> *)(variants);
// Fire the correct event on A.
A<A0, A1, A2> myA;
switch(myConverted.size())
{
case 0:
myA.Go();
break;
case 1:
myA.Go(boost::any_cast<A0>(myConverted[0]));
break;
case 2:
myA.Go(boost::any_cast<A0>(myConverted[0]), boost::any_cast<A1>(myConverted[1]));
break;
case 3:
myA.Go(boost::any_cast<A0>(myConverted[0]), boost::any_cast<A1>(myConverted[1]), boost::any_cast<A2>(myConverted[2]));
break;
default: ;
// throw
}
}
};
int main(int argc, wchar_t* argv[])
{
C<int, B> c;
c.Everything();
}
上面演示了如何从boost::any的向量转到void*然后返回boost::any的向量,对具有正确arity和类型的对象调用函数。