in template overloading, "hi" isn't char* type?

Write your question here.

i set up 2 templates, 1 of the 2 is a explicit specialization.
1
2
template <typename T> void iquote(T); //#1
template <> void iquote<char*>(char* x); //#2 

i hope when i give, say, 10, 10.0, the program would choose #1, and when i give "hey", it will choose #2, but the result is that, it still choose #1, only when i give variable whose type is char* will choose #2.
i was told "hey" and char* x; both char* type and cause they are actually the addr. i'm puzzled...
and how i code is the right way?
Last edited on
"hi" is of type const char[3] so you should specialize on const char*, otherwise the unspecialized version will be a better match.
Last edited on
Add one more template specialization

template <> void iquote<const char*>(const char* x); //#3

wow, thx!
As far as possible, avoid specializing function templates.

In this case for instance, specialization(s) are completely unnecessary.
1
2
3
template <typename T> void iquote(T) ; 
void iquote( char* ) ; 
void iquote( const char* ) ;


To understand why specializing function templates is a bad idea, see:
http://www.gotw.ca/publications/mill17.htm

To understand why specializing function templates is a bad idea, see:
http://www.gotw.ca/publications/mill17.htm


Thanks for the link. Always good stuff.
The downside to preferring overloading over specializing is that you can still call the template version if you explicitly specify the template args (which may sometimes be necessary to avoid ambiguities)

1
2
3
4
5
6
7
8
9
10
template <typename T> void f(T);  // (a)
void f(int);  // (b)


template <typename T>  // for this example, assume T=int
void problematic_function()
{
    T foo;
    f<T>(foo);  // calls (a), not (b)
}


Obviously this is a trivial example because <T> doesn't need to be explicitly specified here... but sometimes it needs to be.


Perhaps the best would be to do both?

1
2
3
4
template <typename T> void f(T);
void f(int);

template <> void f<int>(int x) { f(x); }
Last edited on
> Perhaps the best would be to do both?

It is a poor design idea to demand that users must do two different things in tandem to achieve something that can be achieved by doing just one.

The canonical solution to this problem (and also the problem that function templates can't be partially specialised) is given in the link I had posted earlier. With apologies to those who had read it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

template < typename T > struct ff ;

template <typename T> void f( T t ) { ff<T>::f(t) ; }

template < typename T > struct ff
{ static void f(T) { std::cout << "general\n" ; } } ;

template < typename T > struct ff<T*>
{ static void f(T*) { std::cout << "partial for pointers\n" ; } } ;

template <> struct ff<int>
{ static void f(int) { std::cout << "complete for int\n" ; } } ;

int main()
{
    f('a') ; // general
    int a = 8 ;
    f(a) ; // complete for int
    f(&a) ; // partial for pointers
}


http://ideone.com/FYFFhF
I had read the link, I guess I just stopped before the "Moral 2" part.

Very interesting indeed.
Topic archived. No new replies allowed.