我有一个:header.cpp,header.hpp和一个test_header.cpp。
在header.hpp中,我有:
class MyClass
{
public;
MyClass();
std::string name;
//...code with other variables,methods;
class MySecondClass
{
public:
MySecondClass();
std::string surname;
//..code with other variables,methods
}*MySC;
public:
template<class T>
bool method(T& obj);
{
if (typeid(MyClass)=typeid(obj))
{
MyClass *s= new MyClass();
*s=obj //i want to save everything that i have in obj into s;
//call method "MyMethod" and work with s
}
else if (typeid(MyClass::MySecondClass)=typeid(obj))
{
MyClass::MySecondClass *s1= new MyClass::MySecondClass();
*s1 = obj;
//call "MyMethod" and work with s1;
}
return true;
}
}*mycls;
在test_header.cpp中我有
{
MyClass *mycls = new MyClass();
MyClass::MySecondClass *mysec_cls= new MyClass::MySecondClass();
if (mycls->method<MyClass>(*mycls)
{//code
}
if (mycls->method<MyClass::MySecondClass>(*mysec_cls)
{//code
}
}
我有一个错误,说mysec_cls不是MyClass类型。因为我已经意识到指针转到第一个if而且从不在其他地方。
.h error: no match for operator= in *s1 = obj.
note: candidates are: MyClass& MyClass::operator=(const MyClass&)
我没有这个错误,如果在test_header.cpp我只有一个if和if在模板中我只有if in test_header中的引用,但是如果我对T&amp; obj我有我提到的错误。
为什么呢?怎么改变这个?我正在使用g ++进行编译。
答案 0 :(得分:4)
当你实例化一个模板时,它会被完全编译,而不管代码的哪些分支最终会被执行。在您的特定代码中,即使if
语句将确保仅执行具有有效赋值的分支,也必须编译这两个分支,并且其中一个分支不正确。
考虑简单的非模板化示例:
void foo( int x ) {
if ( true ) {
int y = x;
} else {
std::string s = x;
}
}
虽然永远不会执行第二个分支,但编译器必须确保代码正确(即使它可以优化它),并且它将失败,因为您无法从整数初始化字符串。您的代码中存在同样的问题。
至于如何解决它,最简单的方法是,不使用函数重载解析来代替编写分支,而是将调度解析为适当的代码段。这样你可以有两个不同的函数(或者如果你想要的话可以使用特殊化,但我建议使用不同的重载),每个函数只能使用其中一种类型,这样分配才有效。
答案 1 :(得分:1)
我的水晶球告诉我你以某种方式使你从type_info中检索的类名变形,因为这个名字不是直接的类名,而是一个实现定义的字符串,它充分地从类名派生,以允许相等比较,并且在那个过程中,两个名称都被映射到“MyClass”(即你正在切断内部类的名称),因此它们最终都在同一个处理程序中。
如果要在运行时比较类型,请直接比较type_info节点:
if(typeid(obj) == typeid(MyClass)) ...
如果你在method
中有一个关闭的类型列表(在你的实现中,因为你不能将更多的案例添加到链式if
语句列表中),那么就没有了使用模板的真正原因;定期超载就足够了:
class MyClass
{
std::string name;
// ...
class MySecondClass
{
std::string surname;
// ...
} *mysc;
bool method(MyClass const &obj)
{
MyClass *copy = new MyClass;
*copy = obj;
// ...
}
bool method(MySecondClass const &obj)
{
MySecondClass *copy = new MySecondClass;
*copy = obj;
// ...
}
// ...
};