Jump to content
  • Advertisement
Sign in to follow this  
CJM

Template parameter a pointer?

This topic is 5473 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

Hey, I've been playing around with some templated stuff - a Serialiser similar to the one which is used in Enginuity I think. Normal types serialise properly, but I can't figure out a nice implementation for pointers. In particular, I have the SerialOp(T& object) templated function. Is there an easy way to determine at runtime whether the object is a pointer, without using RTTI? I was thinking of casting the object to a void*, and seeing if that wasn't 0, but I'm not so sure that it would fail for some objects, and can't find information on trying to cast ints to pointers or whatnot. Anywho, best case, would there be any way to exclude pointers from the generated template types [I'm guessing no], and secondly, is there any way to determine quickly and easily if a type is a pointer - would the void* cast work? //end rant CJM

Share this post


Link to post
Share on other sites
Advertisement
The void* cast wont work. It will give you a compile-time error if the type isn't a pointer (using static_cast, however a C-style cast will let you do the cast with builtin types giving you some funky void* pointer), but that's the opposite of what you'd need to exclude pointers from being used as the template parameter.

I'm fairly sure you can't have code that does something like
if(isPointer) {...}
else {...}
so your only option would to be create a scenario that would force a compile-time error if the type is a pointer. To do this check out the boost::concept_check library.

Share this post


Link to post
Share on other sites
Actually, just thought of something.

template<typename I>
void func(I test) {
std::cout << "A normal type!" << std::endl;
}

template<typename I>
void func(I* test) {
std::cout << "A pointer type!" << std::endl;
}

int main() {
int i=1;
int *p=&i;
func(i);
func(p);
return 0;
}


Works with gcc3.2.

Share this post


Link to post
Share on other sites
joanusdmentia,

I'm checking out the Concept Check Library thing you sent to me. I've already tried something like what you describe, but the problem with your second bit of code is that you've got pass by value. I'm using references to get the data into the function, and I'm relatively sure that pointer-to-reference isn't legal. Do you think that the easiest solution would just be then to use T* and T** and then dereference, which is basically equivelent?

CJM

Share this post


Link to post
Share on other sites
There is an alternative, its called type traits, boost has a type traits package:


template < typename T >
struct is_pointer {

enum { val = false };

};


template < typename T >
struct is_pointer<T*> {

enum { val = true };

};

template < typename T >
void SerialOp(const T& obj) {

if(is_pointer<T>::val) {
/* code to handle pointers */
} else {
/* normal code */
}
}


compiler needs partial specialization support which VC++ 6.0 doesn't have.

notice i've used a constant reference, you should do the same

Share this post


Link to post
Share on other sites
Hey snk_kid,

I think that's about as clean as it's gonna get. Thanks.

also, thanks joanusdmentia.

CJM

Share this post


Link to post
Share on other sites
Quote:
Original post by CJM
I'm using references to get the data into the function, and I'm relatively sure that pointer-to-reference isn't legal. Do you think that the easiest solution would just be then to use T* and T** and then dereference, which is basically equivelent?
CJM

Doesn't matter.

template<typename I>
void func(const I& test) {
std::cout << "A normal type!" << std::endl;
}

template<typename I>
void func(I* test) {
std::cout << "A pointer type!" << std::endl;
}



But as snk_kid said, type traits would be better still. (can't believe I didn't think of that!)

Share this post


Link to post
Share on other sites
And, to avoid generating unnecessary code (since T can't be both pointer type and normal type), you can do this:


template<bool> struct switch_t { };

template<class T, bool B>
void serialise(const T& a, switch_t<B>)
{
std::cout << "A normal type!" << std::endl;
}

template<class T>
void serialise(const T& a, switch_t<true>)
{
std::cout << "A pointer type!" << std::endl;
}

template<class T>
void SerialOp(const T& test)
{
serialise(test, switch_t<is_pointer<T>::val>());
}




This will only instantiate the code that actually gets executed.

Share this post


Link to post
Share on other sites
Quote:
Original post by roller
And, to avoid generating unnecessary code (since T can't be both pointer type and normal type), you can do this:

*** Source Snippet Removed ***

This will only instantiate the code that actually gets executed.


while i totally agree that this is a better method, the version i posted the if statement is trivially true or false at compile time thus if optimizations (maybe even then) are turned on i'm sure the compiler can easily eliminate the if statement using dead code elimination.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid

< snip >

compiler needs partial specialization support which VC++ 6.0 doesn't have.

notice i've used a constant reference, you should do the same


Hello,

Maybe this should do the trick (and it does not require partial specialisation AFAIK)


template <typename T> struct is_pointer
{
static inline bool is(T*) {return true;}
static inline bool is(const T&) {return false;}
};

int _tmain(int argc, _TCHAR* argv[])
{
int *pi=0;
int i=0;

if (is_pointer<int>::is(i))
{
std::cout << "i is a pointer" << std::endl;
}
else
{
std::cout << "i is NOT a pointer" << std::endl;
}

if (is_pointer<int>::is(pi))
{
std::cout << "pi is a pointer" << std::endl;
}
else
{
std::cout << "pi is NOT a pointer" << std::endl;
}

std::cin >> i;

return 0;
}



Both VC6 and VC .NET 2003 release mode optimize out the not needed code.

(edit: added VC6 italic stuff ^_^ (this "i logout you while you are editing you post" is rather strange :/ Not sure it is by design...)

Regards,

[Edited by - Emmanuel Deloget on September 28, 2004 9:05:51 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!