Sign in to follow this  

C++ class template member specialization trouble

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

I'm having trouble coming up with the correct template syntax to specialize a member function of a template class. Here's my example:

template <typename T>
class MyClass
{
public:
T DoStuff()
{
T ret;
double phase = someThing;

// How would this get called?
ret = MySin(phase);

return ret;
}

private:

// How should these functions be written?
int MySin(double phase)
{
return static_cast<int>(floor(0.5 + INT32_MAX * sin(phase)));
}

float MySin(double phase)
{
return static_cast<float>(sin(phase));
}

// Also specialize for shorts, maybe 64-bit ints, etc.
};


Also, can I specialize some of them (like the fixed-point versions so I can define the INT*_MAX value) but use a generic one for the others (just use the 'float' version for all floating point types).

Thanks.

Share this post


Link to post
Share on other sites
In C++, function overloads cannot differ by just their return types; parameter types are generally what is used to determine which overload is called. The reason you current code doesn't work is the compiler, given just the parameter type of double, doesn't know which MySin overload to call.


Thankfully, by using some easy tricks, we can add a layer of information to the overload resolution process, and effectively get overloads by return type without actually doing so directly:

template <typename T>
class MyClass
{
public:
T DoStuff()
{
double phase = SomeThing;
return MySin<T>(phase);
}

private:

// First we must inform the compiler that MySin is a templated method
// with a differing return type based on the template type parameter.
// To catch template parameters that we didn't specialize for, we use
// a non-compilable function. Templates are not elaborated until they
// are instantiated with a given type, so this code will only cause a
// compile error if the value of T is unexpected.
template <typename T>
T MySin(double phase)
{
static_assert(false, "Invalid specialization");
}

// Now we do the dirty work and define each specialization we need
template <>
int MySin<int>(double phase)
{
return static_cast<int>(floor(0.5 + INT32_MAX * sin(phase)));
}

template <>
float MySin<float>(double phase)
{
return static_cast<float>(sin(phase));
}

// Repeat for other types
};

Share this post


Link to post
Share on other sites

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