In the below code snippet,
template<typename T1>
void func(T1& t)
{
cout << "all" << endl;
}
template<typename T2>
void func(T2 &t)
{
cout << "float" << endl;
}
// I do not want this
// template<> void func(float &t)
int main()
{
int i; float f;
func(i); // should print "all"
func(f); // should print "float"
return 0;
}
I would like to have the templates modified which by passing any type other than float will print "all" and passing float will print "float". I do not want template specialization, instead have partial specialization which will act accordingly based on input type. How should i go about it. Thanks in advance.
Well the scenario, i'm currently facing is like, I need to have the following defined,
template<typename T1>
void func(T1 &t)
{
cout << "t1" << endl;
}
template<typename T2>
void func(T2 &t)
{
cout << "t2" << endl;
}
The following calls should print "t2"
func(int) // print "t2"
func(float) // print "t2"
func(string) // print "t2"
The following calls should print "t1"
func(char) // print "t1"
func(xyz) // print "t1"
...
func(abc) // print "t1"
some kind of grouping like the above where few should call the partial specialization implementation and others should call the default implementation.
This is how to make it work without ugly syntax
a and !b and !c
forenable_if
in case of arbitrary number of conditions.If we know that partial specialization don't work work function but work with classes, let's use classes! We should hide it from people, but we can use them!
OK, code:
(1) First of all just for every type call helper. No specialization for functions.
(2) Here we add one dummy argument. We don't have to specify it on calling because it's default to
void
(3) In 3 we just givevoid
, when we allowT
and anything else (or SFINAE as in our case). One important thing is that we shouldn't allow someT
twice or more.Notes:
We can also change default type to std::true_type, after that we will be able to get rid of
std::enable_if
(std::enable_if<some_trait<T>::value>
will be change to justsome_trait<T>::type
). I'm not sure whichThis code uses type traits from C++11. If you don't have c++11 support you may write your own traits or use type traits from
boost
Live example
As Tomalak already said in his answer you can not partially specialize a template function, but if you change your function to be a static member function in a template class, you could do it.
However, a better approach would be function overloading.
Write a type traits class for your condition:
Use boost::enable_if and disable_if:
You can combine function overloading with templates. So:
You cannot partially specialise functions in C++.
Perhaps this is not the terminology you mean. You can use templates like
boost::is_same<T1, T2>
to perform conditional logic based on the given template parameter. You can also useT
in any place where you'd use any other type, such as intypeid(T).name()
:(Although I'd not recommend using typeid().name() as its value is not specified by the standard and can vary from the type written in your code, to a mangled symbol, or the lyrics to Pokerface.)
Addendum Like other answerers, I would personally choose template specialisation itself or just plain ol' function overloading. I don't know why you're averse to them, but that is what they are there for.