【发布时间】:2015-02-15 08:29:38
【问题描述】:
我正在开发一个简单的游戏引擎,它为游戏对象提供了一个基类,可以使用特定游戏的子类进行扩展。我需要编写一个函数,它可以获取一个文件,从中解析对象名称,并在游戏中实例化相应的对象;提供一种在文件中存储关卡数据的机制。我曾希望使用元编程来创建一个函数,允许调用者传入可变数量的数据类型,并生成一个函数来搜索与文件中这些类型对应的名称。它的使用看起来像这样(使用模板):
fileParseFunction<type1, type2 type3>("filename");
将生成一个等效于:
fileParseFunction(string filename)
{
//code that opens file called "filename" and handles tokenizing/parsing
if(token == "type1")
{
gameWorld.add(new type1());
}
elseif(token == "type2")
{
gameWorld.add(new type2());
}
elseif(token == "type3")
{
gameWorld.add(new type3());
}
//other code to finish loading the level
}
使用参数“文件名”调用。这应该适用于可变数量的类型(示例中为 3)。我编写了一些代码来测试涉及生成类似函数的概念。它使用模板将类型名称符号转换为字符串(在我最终希望编写的函数中进行比较时需要使用它),还使用可变参数模板生成一个函数,该函数打印作为模板参数传入的所有类型的名称。这里是:
#define TypeNameTemplate(a) template<> inline const char* typeName<a>(void) { return #a; }
template <typename T>
inline const char* typeName(void) { return "unknown"; }
TypeNameTemplate(int);
TypeNameTemplate(std::string);
TypeNameTemplate(double);
TypeNameTemplate(bool);
TypeNameTemplate(float);
/*template <>
inline const char* typeName<int>(void) { return "int"; }*/
template <typename T> inline void printtypes()
{
std::cout << typeName<T>();
}
template <typename T, typename... Args> void printtypes()
{
std::cout << typeName<T>() << std::endl;
printtypes<Args...>();
}
using namespace std;
int main()
{
//string a = typeName<int>();
//print();
printtypes<int, double, string, bool, float>();
return 0;
}
printtypes() 应该生成一个等效于:
void printtypes()
{
std::cout << typeName<int>();
std::cout << typeName<std:string>();
std::cout << typeName<double>();
std::cout << typeName<bool>();
std::cout << typeName<float>();
}
但是,在编译过程中我得到了这个错误:
E:\C++ projects\templateTest\main.cpp:26:5: 注意:候选人是: E:\C++ 项目\templateTest\main.cpp:18:35: 注意:void printtypes() [with T = float] E:\C++ 项目\templateTest\main.cpp:23:46: 注意:void printtypes() [with T = float; Args = {}]
似乎在递归到达可变参数包的末尾时,编译器不知道是调用仅针对具有最后一个类型的一种类型的模板,还是调用具有最后一个类型的可变参数模板pack 加上一个空的参数包。我在 C++ 中尝试做的事情是否可行/实用,有没有办法让编译器知道它应该将单参数模板用于递归调用的基本/最终情况?
【问题讨论】:
标签: c++ templates recursion metaprogramming game-engine