template<class T> error
I have a: header.cpp, header.hpp and a test_header.cpp.
In header.hpp i've i have:
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;
In test_header.cpp I have
{
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
}
}
I have an error saying that mysec_cls is not of type MyClass. As i've realised the pointer goes to the first if and never on else.
.h error: no match for operator= in *s1 = obj.
note: candidates are: MyClass& MyClass::operator=(const MyClass&)
I don't have this error if in test_header.cpp i have just one if and if in template i only have the reference from the if in test_header, but if ihave more than one reff开发者_如何学JAVAerence to T& obj i have the error i've mentioned.
Why? how to change this? i am compiling using g++.
When you instantiate a template it gets fully compiled, independently of what branches of the code will get eventually executed. In your particular code, even if the if
statement will ensure that only the branch that has the valid assignment gets executed, both branches must be compiled, and one of them is not correct.
Consider the simple non templated example:
void foo( int x ) {
if ( true ) {
int y = x;
} else {
std::string s = x;
}
}
While the second branch will never be executed, the compiler must ensure that the code is correct (even if it can optimize it away), and it will fail as you cannot initialize a string from an integer. The same problem is present in your code.
As to how to solve it, the simplest way would be that instead of writing branches you use function overload resolution to resolve the dispatch to the appropriate piece of code. That way you can have two different functions (or specializations if you want, but I'd recommend different overloads), each of which works only with one of the types, so that the assignment is valid.
My crystal ball tells me that you are somehow transmogrifying the class name you retrieve from the type_info, as this name is not directly a class name, but rather an implementation-defined string that is sufficiently derived from the class name to allow equality comparison, and that in that process, both names are mapped to "MyClass" (i.e. you are cutting off the inner class's name), hence both end up in the same handler.
If you want to compare types at runtime, compare the type_info nodes directly:
if(typeid(obj) == typeid(MyClass)) ...
If you have a closed list of types you handle in method
(and in your implementation, there is, because you cannot add more cases to a list of chained if
statements), there is no real reason to use a template; a regular overload is enough:
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;
// ...
}
// ...
};
精彩评论