Atul
Atul

Reputation: 4320

C++: How to work with data type of parameter in member function template

I've to do activities in my template based on type of class I get as parameter:

In Class.h

class SomeClass;
class SomeOtherClass;

class Class 
{
public:
    template <typename T> void function(T value);
};

In Class.cpp

template<typename T> void Class::function(T value) 
{
    // Whole lots of common code here

    if (T == SomeClass)
    {
       // Do something by casting value to SomeClass
       SomeClass* ptrSomeClassObj = (SomeClass*) &value;
       ptrSomeClassObj->MemberFunctionOfSomeClass();
    }
    else
    {
       // Do something else
    }

    // Whole lots of common code here
}

Now I've these questions:

  1. Here if (T == SomeClass) is not correct syntax. How shall I do this?

  2. Type casting of T the way I've done doesn't give me any syntax error. But is this appropriate to do like this? I believe C++ has better ways.

Update: Not really looking for Template specialization because it would replicate lots of common code (as mentioned in code above) in specialized functions.

Upvotes: 0

Views: 73

Answers (2)

Mark B
Mark B

Reputation: 96241

I'm pretty sure the most straightforward way to do this is overloading and delegating the work:

class SomeClass;
class SomeOtherClass;

class Class 
{
public:
    template <typename T> void function(T value);

    template <typename T> void function_detail(T value);
    void function_detail(SomeClass value);
};

template<typename T> void Class::function(T value) 
{
    // Whole lots of common code here

    function_detail(value);

    // Whole lots of common code here
}

template<typename T> void Class::function_detail(T value) 
{
    // Do something else.
}

void Class::function_detail(SomeClass value) 
{
    value.MemberFunctionOfSomeClass();
}

Upvotes: 1

Fabian Knorr
Fabian Knorr

Reputation: 3184

You'll want to move the code depending on the actual type of T to a second member (or static) function wich you can then overload, passing any values resulting from the common code as parameters (someParam):

class SomeClass;
class SomeOtherClass;

class Class 
{
public:
    void typeDependent(SomeClass value, int someParam);
    template <typename T> void typeDependent(T value, int someParam);

    template <typename T> void function(T value);
};

void Class::typeDependent(SomeClass value, int someParam) 
{
    value->MemberFunctionOfSomeClass(someParam);
}

template<typename T> void Class::typeDependent(T value, int someParam) 
{
    // Do something else
}

template<typename T> void Class::function(T value) 
{
    int someParam = 123; // Whole lots of common code here
    typeDependent(value, someParam);
    // Whole lots of common code here
}

This allows you to call functions that only exist for the SomeClass type without casting. Note that I didn't use template specialization but overloading - Using specialization for function templates is generally a bad idea due to their complicated resolution rules.

If you insist on writing this distiction as a conditional, you can use the std::is_same template (Requires C++11):

#include <type_traits>

template<typename T> void Class::function(T value) 
{
    if (std::is_same<T, SomeClass>::value)
    {
         // Do something
    }
    else
    {
        // Do something else
    }
}

This will require you to use a cast like you did in the original post as the function will not compile for T != SomeClass otherwise.

Upvotes: 3

Related Questions