Jump to content
  • Advertisement
Sign in to follow this  
DevFred

template instantiation

This topic is 3667 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 have a function template
template<typename F, typename I, int M, int C>
string qqq(F f)
{
    // ...
}
Now there are only two combinations that make sense for my application:
float, int, 23, 255 and
double, long long, 52, 1023
Is it possible to instantiate the template for only these two combinations, so one can use qqq(float) and qqq(double) without explicitly stating the other three parameters? With class templates one can use typedefs, but I don't know how do to it with function templates.

Share this post


Link to post
Share on other sites
Advertisement
The simplest solution jumps at me:

string qqq(float f)
{
return qqq_impl<float,int,23, 255>(f);
}

string qqq(double d)
{
return qqq_impl<double, long long, 52, 1023>(f);
}


Where qqq_impl could be hidden in a private namespace inside the source file.

Share this post


Link to post
Share on other sites
There are several possibilities, the easiest being to use overloading instead of templates:

namespace detail
{
template<typename F, typename I, int M, int C>
string qqq_impl(F f) { /* ... */ }
}

string qqq(float f) { return detail::qqq_impl<float, int, 23, 255>(f); }
string qqq(double f) { return detail::qqq_impl<double, long long, 52, 1023>(f); }




EDIT: well, my solution has a detail namespace [rolleyes]

Share this post


Link to post
Share on other sites
Thanks to both of you!

I came up with another solution involving function pointers. I cannot use overloading with it (the function pointers cannot have the same name as the template function), but that's not so bad.
string (*xxx)(float) = qqq<float, int, 23, 255>;
string (*yyy)(double) = qqq<double, long long, 52, 1023>;

Share this post


Link to post
Share on other sites
The other way is to encapsulate the parameter set.

template<typename F>
struct qqq_traits;

template<>
struct qqq_traits<float>
{
typedef float F;
typedef int I;
static const int M = 23;
static const int C = 255;
};


struct qqq_traits<double>
{
typedef double F;
typedef long long I;
static const int M = 52;
static const int C = 1023;
};

template<typename F>
string qqq(F f)
{
typedef qqq_traits<F> traits;
typedef typename traits::I I;
const int M = traits::M;
const int C = traits::C;
// ...
}


This is useful when there are certain sets of classes which should be treated similarly (see, for example, iterator_traits).

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Thanks to both of you!

I came up with another solution involving function pointers. I cannot use overloading with it (the function pointers cannot have the same name as the template function), but that's not so bad.
string (*xxx)(float) = qqq<float, int, 23, 255>;
string (*yyy)(double) = qqq<double, long long, 52, 1023>;

The compiler is unable to apply certain optimizations such as inlining here. I wouldn't suggest it.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
You don't really need the F typedef inside the struct, right?

Depends on the use but, in this case, no.

Share this post


Link to post
Share on other sites
Not really important for the question, but the double C should be 2047 instead of 1023 (it is used to mask of the exponent, and there are 11 bits for that in a double, not 10).

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!