Sign in to follow this  

templates and checking what class it is

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

if (typeid(T) == typeid(CMyClass)) {} should do it.

EDIT: Fixed. [smile]

[Edited by - Ra on August 27, 2004 11:15:25 AM]

Share this post


Link to post
Share on other sites
Yeah, but that requires RTTI. You might want to check out traits at boost.org. Can't give you more details because of my lack of knowledge, but the docs should give enough info.

Share this post


Link to post
Share on other sites
Quote:
Original post by CoffeeMug
Yeah, but that requires RTTI. You might want to check out traits at boost.org. Can't give you more details because of my lack of knowledge, but the docs should give enough info.


RTTI? could you explain what that is.
-CProgrammer

Share this post


Link to post
Share on other sites
Quote:
Original post by CProgrammer
How do I check wether it is a given class.


You don't - you write a specialisation (or, for a function, an overload). Can you show more code (is it a function, a class... ?)

edit - though you can do a bit of metaprogramming and make a class that will - at compile time - do a type comparison. If your compiler does support partial specialisations (i.e. not VC6)


template<class T, class U>
struct IsSameClass
{
enum { result = 0 };
};

template<class T> struct IsSameClass<T,T>
{
enum { result = 1 };
};

...


if ( IsSameClass<T, CMyClass>::value )
{

}


Note that it is a static type check.
Also, see boost::type_traits and boost::mpl, which have workarounds for compilers without PTS.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
You don't - you write a specialisation (or, for a function, an overload).

Ahh, yeah, but specialization isn't always an option (although in this case it unarguably is a better solution).

Share this post


Link to post
Share on other sites
BTW, Ra, there is no standard support for typeof (I hope that'll change), you probably meant typeid

Quote:
Original post by CoffeeMug
Ahh, yeah, but specialization isn't always an option (although in this case it unarguably is a better solution).


When you start playing with templates, RTTI is rarely the right answer. Specialization and metaprogramming generally are. :)

With boost::type_traits, you would do
if (::boost::is_same<T,U>::value)
{

}


Which is about the same thing as I've written, except they've coded it 'right'. [grin]

Share this post


Link to post
Share on other sites
boost looks nice.
But after you mentioned overloaded functions I thought odf another solution. I first thought Id end up writing the same code twice but:
Since theres only two types how about an abstract interface class for the two. Then have an overloaded function that both just call a third function which takes a pointer to the abstract class.

-CProgrammer

Share this post


Link to post
Share on other sites
Basically, depending on the situation, it's probably best to use the solution that's closest to the top of the list:
1. Template specialization
2. Type traits
3. RTTI

RTTI should of course be used in situations where it's impossible to determine the type at compile time (polymorphic cases).

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
BTW, Ra, there is no standard support for typeof (I hope that'll change), you probably meant typeid
...you're kidding me, right?

hmm, it looks like typeid is what I meant, but I've always used typeof.. didn't know it wasn't standard. *shrug*

Share this post


Link to post
Share on other sites
Quote:
Original post by Ra
hmm, it looks like typeid is what I meant, but I've always used typeof.. didn't know it wasn't standard. *shrug*

You could always use sizeof trick described in Modern C++ Design [wink]

Share this post


Link to post
Share on other sites
Quote:
Original post by Ra
hmm, it looks like typeid is what I meant, but I've always used typeof.. didn't know it wasn't standard. *shrug*


typeof is supported by g++ and returns an actual type toke, not a type_info object you can compare.

That is, you can write: typeof(3.5f) x = 3.5f;, but not typeof(3.5f) == typeof(3.5f) as it would amount to writint float == float.

Note that for the usage typeof(3.5f) x = 3.5f;, there is a proposal to allow auto x = 3.5f; to have that meaning. Thus my hopeful stance. [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Note that for the usage typeof(3.5f) x = 3.5f;, there is a proposal to allow auto x = 3.5f; to have that meaning. Thus my hopeful stance. [smile]

Python programmers managed to infiltrate the C++ committee? [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by CProgrammer
I first thought Id end up writing the same code twice but


You don't have to write the entire function twice, you can just write an overloaded function to replace that single if statement.

Quote:
Then have an overloaded function that both just call a third function which takes a pointer to the abstract class.


You're programming in C++, use a reference, not a pointer:


template<class T>
void foo(T& arg)
{
/* stuff */
foo_helper(arg);
/* stuff */
}

template<class T>
void foo_helper(T& arg)
{
/* Not CMyClass */
}


template<>
void foo_helper(CMyClass& arg)
{
/* CMyClass */
}


Along with any other arguments you might need to manipulate foo's local variables from foo_helper.

Share this post


Link to post
Share on other sites
Quote:
Original post by CoffeeMug
Python programmers managed to infiltrate the C++ committee? [grin]


Not quite, it's still static typing. The type is fixed at compile-time and once it has been set, it won't change: x will always be a float you can't later turn it into a std::string. You just get implicit typing in addition to explicit typing. It's closer to Haskell or O'Caml than to Python.

Share this post


Link to post
Share on other sites
Yeah, I realize it's all predetermined in compile time. There's really no way to hack C++ type system to do dynamic type changes. It's just that that example looked a bit Pythonish [smile]

Share this post


Link to post
Share on other sites
Another way wuld be to derive ALL your classes from a single global class, that contains some int giving its type, or a string, or both (which can be useful for debugging)



typedef enum _EClassType{
ectBaseOfAll = 1,
...... // enumerate your classes
ectA,
ectB,
} EClassType;

class CBaseOfAll{
public:
CBaseOfAll(){
ectClassType = ectBaseOfAll;
csClassName = "CBaseOfAll";
}

bool IsSameType(CBaseOfAll *ptr){
return (ectClassType == ptr->ectClassType);
}

EClassType ectClassType;
CString csClassName;
};

class A : public CBaseOfAll{
public:
A(){
ectClassType = ectA;
csClassName = "A";
//// continue with a custom destructor
}
};

class B : public CBaseOfAll{
public:
B(){
ectClassType = ectB;
csClassName = "B";
//// continue with a custom destructor
}
};

A *class1 = new A();
B *class2 = new B();
A *class3 = new A();

if(class1->IsSameType(class2))
print("class2 is same");
else
print("class2 is diff"); // this will be printed

if(class1->IsSameType(class3))
print("class3 is same"); // this will be printed
else
print("class3 is diff");




Thats my method, codewise, its slightly more work than using typeid(), but in the end proves to be faster
there is another plus in doing it the way i have
with the csClassName, u can implement a class factory, and when passing derived classes cast as the base type, functions can be aware of what they're getting

Share this post


Link to post
Share on other sites
Quote:
Original post by caesar4
Another way wuld be to derive ALL your classes from a single global class, that contains some int giving its type, or a string, or both (which can be useful for debugging)


Ewww. [dead]

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Quote:
Original post by caesar4
Another way wuld be to derive ALL your classes from a single global class, that contains some int giving its type, or a string, or both (which can be useful for debugging)


Ewww. [dead]


ewww u [imwithstupid]

Share this post


Link to post
Share on other sites
I definately wouldn't go for auto. It introduces a lot of potential problems and neccesitates the use of a true runtime. Consider:

auto foo(int x) {
if(x > 0) {
return SomeClass();
}
return x;
}

int main() {
int x = foo(-1);
return 0;
}

The compiler has no way of knowing whether the conversion will succeed at runtime. Making this an error just skirts the general problem. Adding auto would require so many restrictions on it that it isn't worth it anyway.

This is kinda why the ISO committe sucks a bit. It's also why it moves so slow. Too many independent people with independent leanings..so unneccesary things make it into the language..such as....crap...I can't remember the specific annoying example at the moment..I had a big long talk with Herb about it though...I'll get back to you.

Share this post


Link to post
Share on other sites

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this