overloaded methods: reference to array and a pointer.

P

__PPS__

Hello everybody, I'm not sure but I thought that sometime ago I had
class with two overloaded methods:
void func(const char*);
and
template<int N>func(const char (&arr)[N]);

so, that whenever I call func("some text") then size of the text will
be known at compile time instead of doing strlen()
I'm sure that long time ago I got it working somehow, but now when I
needed and implemented a similar solution I see that it doesn't work.
(stepping with debugger shows that pointer version is used in all
cases)
I'm using vs2005...
about that working code that I had a couple years ago ... I remember
that I used boost enable if and typetraits/mpl libraries heavily and
possibly I made it working thanks to that libraries (probably, instead
of const char * version I had enable_if(not-array<>) or something like
this). Also, it's possible that I was using g++ and that's why it was
working.
Now, I can't use boost, so I tried to convert const char* version to
SFINAE-like template that would instantiate only in const char * case,
but in this case I got error that two of the functions could be used!!
(kind of, in case when const char* version wasn't templated array
version wasn't ambiguous)... wtf??


So, I'm quite surprised now that if I func("some text") then const
char * version is called instead of templated array-ref version. As
far as I'm concerner typeof("some text") is const char[X] it it's
convertible to const char *...
Can anybody comment on this problem?
thanks
 
N

Neelesh Bodas

Hello everybody, I'm not sure but I thought that sometime ago I had
class with two overloaded methods:
void func(const char*);
and
template<int N>func(const char (&arr)[N]);

Missing return type. Assuming it returned void, you meant:
template said:
so, that whenever I call func("some text") then size of the text will
be known at compile time instead of doing strlen() [boost etc portion chopped]
Now, I can't use boost, so I tried to convert const char* version to
SFINAE-like template that would instantiate only in const char * case,
but in this case I got error that two of the functions could be used!!
(kind of, in case when const char* version wasn't templated array
version wasn't ambiguous)... wtf??

So, I'm quite surprised now that if I func("some text") then const
char * version is called instead of templated array-ref version. As
far as I'm concerner typeof("some text") is const char[X] it it's
convertible to const char *...
Can anybody comment on this problem?
thanks

13.3.3.1 indicates that "when a template function specialization and
non-template function are equally good candidates for overloaded
match, the non template version will be given preference."

Observe that for the call -
function("some text")
the template function specialization for -
template <int N> void func(const char (&arr)[N]);
will be done with N= 10. Further, note that following two are
equally good candiates for resolution of f("some text")

void func(const char*); // non-template function
template<> void func(const char(&arr)[10]); // template-
specialization

According to the rule stated above, the non-template version will be
preferred.

-N
 
P

__PPS__

Observe that for the call -
function("some text")
the template function specialization for -
template <int N> void func(const char (&arr)[N]);
will be done with N= 10. Further, note that following two are
equally good candiates for resolution of f("some text")

void func(const char*); // non-template function
template<> void func(const char(&arr)[10]); // template-
specialization


Ok, this is clear but, what's the correct type of "some text"?? It's
not const char *, it's an array that that's convertible to const char
*. If it was const char * then it would never work with reference to
array version. So... what we have is two functions one is template
that accepts type as-is and another non-template function that accepts
const char * (something that the array is convertible to). Another
step was to convert that const char * version to templated function in
which case I got two templated methods, one of them takes array and
the other one takes pointer and I got error: ambiguous call. That
makes no sense to me... Ok, if there's any problem with "some text",
then let's put it like this: char arr[] = "some text"; and even if I
use arr I still get the same problem. About boost... I think that I
used enable_if<is array> and that's why pointer and array versions
were not ambiguous. I'll try it today
 
P

__PPS__

Problem is solved!! More over I have two working solutions at the end.
One of them is this:

/// ver.1
template<class T, class R>struct is_char_array{};
template<int N, class R>struct is_char_array<const char[N],
R>{ typedef R type; };

template<class T, class R>struct is_char_pointer{};
template<class R>struct is_char_pointer<const char*, R>{ typedef R
type; };
template<class R>struct is_char_pointer<char*, R>{ typedef R type; };

template<class T> typename is_char_array<T, ELib::String>::type
func(const T &arr){
... array version
}

template<class T> typename is_char_pointer<T, ELib::String>::type
func(const T &p){
... pointer version
}

the other solution is even better and I really like it!

/// ver.2
ELib::String func(const char * const & arr){
... pointer version
}

template<int N>ELib::String func(const char (& arr)[N]){
... array version
}

That was simple... the first solutions for sure would not be allowed
into our project (possibly because my managers wouldn't be convinced
that this code cannot reboot system at some random time), but the
second solutions is really good and doesn't use fancy stuff. Any
comments on any of the two solutions, any problems with them?
 
P

__PPS__

Well... I was to quick to declare victory... I see a very strange
behavior now. The second solution works fine, BUT only in free
standing functions. Once I make class methods with the same functions
then pointer version is always used. Seems like a bug in compiler. Any
thoughts about that?
 
P

__PPS__

Opps, sorry, my mistake, when copying to groups my code I made changes
from [reference to pointer to const chars] to [cont reference to
pointer to const chars] and in that case obviously nothing would work
just like if I was passing pointer by value.
here's the fixed pointer version:
ELib::String func(const char * & arr){
... pointer version
}

obviously there's a drawback that const pointers cannot be used, first
version doesn't seem to suffer from such problem. At the end after I
made some more updates to the first version and tested it with 6
different compilers I decided to use it. There's one of the most
important platforms that my code has to run on and I haven't tested it
yet, hope it works there... anyways, I can always go back to the old
version.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top