问题描述
|
我有一个: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,而在test_header中我仅具有if的引用,但是如果我对T&obj的引用不止一个,则我有错误i \'我提到过。
为什么?如何改变呢?我正在使用g ++进行编译。
解决方法
当实例化一个模板时,它将完全编译,而与最终将执行代码的分支无关。在您的特定代码中,即使
if
语句将确保仅执行具有有效分配的分支,也必须编译两个分支,并且其中一个不正确。
考虑简单的非模板化示例:
void foo( int x ) {
if ( true ) {
int y = x;
} else {
std::string s = x;
}
}
虽然永远不会执行第二个分支,但是编译器必须确保代码正确(即使可以对其进行优化),并且由于您无法从整数初始化字符串而将失败。您的代码中存在相同的问题。
关于如何解决它,最简单的方法是使用函数重载解析而不是编写分支来解析对适当代码的调度。这样,您可以拥有两个不同的函数(如果需要,可以使用专门的函数,但是我建议使用不同的重载),每个函数仅适用于其中一种类型,因此赋值是有效的。
,我的水晶球告诉我,您正在某种程度上对从type_info检索到的类名进行迁移,因为该名称不是直接的类名,而是从类名充分派生的用于实现相等性比较的实现定义的字符串,并且在该过程中,两个名称都映射到\“ MyClass \”(即,您要切断内部类的名称),因此两个名称最终都位于同一处理程序中。
如果要在运行时比较类型,请直接比较type_info节点:
if(typeid(obj) == typeid(MyClass)) ...
如果您在ѭ6handle中处理过类型的封闭列表(在您的实现中,因为不能将更多的情况添加到链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;
// ...
}
// ...
};