我想做以下事情: 我有一个模板类,有3种类型:
file:util.h
template <typename T1, typename T2, typename T3>
DoSomething(string p1, string p2, string p3){
// Do something.
}
main.cc导入了很多类,我需要遍历很多类类型。
file:main.cc
# include "util.h"
# include "type1.h"
# include "type2.h"
# include "type3.h"
# include "type4.h"
REGISTER("process1", type1::Type1);
REGISTER("process2", type2::Type2);
REGISTER("process3", type3::Type3);
REGISTER("process4", type4::Type4);
int n = NumRegisteredStrings() // returns 4 (for process1...process4)
for (i=0; i < n-2; i++) {
p1 = FetchStringName(i);
p2 = FetchStringName(i+1);
p3 = FetchStringName(i+2);
// When i=0, p1, p2, p3 = (process1, process2, process3) and
// t1, t2, t3 are (Type1, Type2, Type3)
// When i=1, p1, p2, p3 = (process2, process3, process4) and
// t1, t2, t3 are (Type2, Type3, Type4)
const auto t1 = FetchTypeFromRegistry(p1);
const auto t2 = FetchTypeFromRegistry(p2);
const auto t3 = FetchTypeFromRegistry(p3);
DoSomething<t1, t2, t3>(p1, p2, p3);
}
手工创建太多的调用很痛苦。我对注册管理机构的评价很少,但我们并不知道它们是如何运作的。有一个很好的资源,有一个例子,看看我是否可以用它来完成这项工作?
否则,我最终会编写以下代码(容易出错):
main () {
DoSomething<Type1, Type2, Type3>("process1", "process2", "process3");
DoSomething<Type2, Type3, Type4>("process2", "process3", "process4");
}
我真正想要的是
void Helper(string string1, string string2, string string3) {
DoSomething<GetRegisteredType(string1),
GetRegisteredype(string2),
GetRegisteredType(string3)>(string1, string2, string3);
}
main () {
// I should not have to specify the type names here.
// They should be automatically inferred in calling the templated function.
Helper("process1", "process2", "process3");
Helper("process2", "process3", "process4");
}
答案 0 :(得分:0)
您的问题非常模糊,但看起来您正在尝试最小化您必须维护的类似代码的数量。这可以使用预处理程序指令完成。
例如,如果您必须执行以下操作:
a0(arg_0);
b0(arg_0);
a1(arg_1);
b1(arg_1);
a2(arg_2);
b2(arg_2);
您可以像这样定义预处理器指令:
#define AB(n) \
a##n(arg_##n); \
b##n(arg_##n);
现在第一个代码段相当于
AB(0)
AB(1)
AB(2)
如果你想迭代多个数字,你可以使用可变参数或Boost.Preprocessor。
例如,使用BOOST_PP_REPEAT:
#include <boost/preprocessor/repetition/repeat.hpp>
#define AB(z, n, text) \
a##n(arg_##n); \
b##n(arg_##n);
BOOST_PP_REPEAT(3, AB, nil)
答案 1 :(得分:0)
如果我理解你正确,你想要注册名称或typeid的类型,以便以后能够对它进行一些操作。
此代码在visual studio 2013中经过测试,工作正常。
#include <iostream>
#include <map>
using namespace std;
class Interface
{
public:
virtual std::string Greetings() = 0;
};
class Type1:public Interface
{
public:
Type1()
{
}
~Type1()
{
}
std::string Greetings()
{
return "Hello from Type1";
}
private:
};
namespace SomeNamespace
{
class Type2:public Interface
{
public:
Type2()
{
}
~Type2()
{
}
std::string Greetings()
{
return "Hello from SomeNamespace::Type2";
}
private:
};
}
typedef Interface* (*Delegate)(void);//signature of the fucntion pointer
std::map< std::string, Delegate > objectFactories;
template<class Type> Interface* GetInstance()
{
return new Type();
}
int _tmain(int argc, _TCHAR* argv[])
{
objectFactories["Type1"] = GetInstance < Type1 > ;
objectFactories["SomeNamespace::Type2"] = GetInstance < SomeNamespace::Type2 > ;
for (auto&item : objectFactories)
{
cout << "Greetings from '" << item.first.c_str() << "' is \"" << item.second()->Greetings().c_str() << "\"" << endl;
}
cin.get();
return 0;
}
Greetings from 'SomeNamespace::Type2' is "Hello from SomeNamespace::Type2"
Greetings from 'Type1' is "Hello from Type1"