Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How do I prevent a function template take precedence over inheritance?

Reply
Thread Tools

How do I prevent a function template take precedence over inheritance?

 
 
DeMarcus
Guest
Posts: n/a
 
      04-23-2010
Hi,

I have a function template structure like this.

struct A
{
};

struct B : A
{
}

class SomeClass
{
public:

template<typename T>
void fnc( const T& t )
{
std::cout << "Template" << std::endl;
}

void fnc( const A& a )
{
std::cout << "Non-template" << std::endl;
}
};

int main()
{
SomeClass sc;
sc.fnc( A() ); // This gives me "Non-template".
sc.fnc( B() ); // Error! This gives me "Template"
// even though B inherits from A.
}

What's the proper way making instances of B access the non-templated
function?

Thanks,
Daniel
 
Reply With Quote
 
 
 
 
pfultz2
Guest
Posts: n/a
 
      04-23-2010
On Apr 23, 11:00*am, DeMarcus <(E-Mail Removed)> wrote:
> Hi,
>
> I have a function template structure like this.
>
> struct A
> {
>
> };
>
> struct B : A
> {
>
> }
>
> class SomeClass
> {
> public:
>
> * * template<typename T>
> * * void fnc( const T& t )
> * * {
> * * * *std::cout << "Template" << std::endl;
> * * }
>
> * * void fnc( const A& a )
> * * {
> * * * *std::cout << "Non-template" << std::endl;
> * * }
>
> };
>
> int main()
> {
> * * SomeClass sc;
> * * sc.fnc( A() ); *// This gives me "Non-template".
> * * sc.fnc( B() ); *// Error! This gives me "Template"
> * * * * * * * * * * // even though B inherits from A.
>
> }
>
> What's the proper way making instances of B access the non-templated
> function?
>
> Thanks,
> Daniel


Use enable_if and make them both templates:
class SomeClass
{
public:

template<typename T>
void fnc( const T& t, typename enable_if<inherits<T, A> >::type *
dummy = 0 )
{
std::cout << "Inherits A" << std::endl;
}

template<typename T>
void fnc( const T& t )
{
std::cout << "Doesnt inherit A" << std::endl;
}

};

You can read about enable_if here: http://www.boost.org/doc/libs/1_42_0...enable_if.html
 
Reply With Quote
 
 
 
 
DeMarcus
Guest
Posts: n/a
 
      04-23-2010
Victor Bazarov wrote:
> DeMarcus wrote:
>> Hi,
>>
>> I have a function template structure like this.
>>
>> struct A
>> {
>> };
>>
>> struct B : A
>> {
>> }
>>
>> class SomeClass
>> {
>> public:
>>
>> template<typename T>
>> void fnc( const T& t )
>> {
>> std::cout << "Template" << std::endl;
>> }
>>
>> void fnc( const A& a )
>> {
>> std::cout << "Non-template" << std::endl;
>> }
>> };
>>
>> int main()
>> {
>> SomeClass sc;
>> sc.fnc( A() ); // This gives me "Non-template".
>> sc.fnc( B() ); // Error! This gives me "Template"

>
> It's not an error. The template, since it's allowed to be instantiated,
> participates in the overload resolution. And because the compiler is
> able to deduce 'T' as 'B' (most likely), its argument conversion
> (reference binding, which is like the "identity") has a higher rank than
> the non-template's "derived-to-base" conversion. That's why the
> compiler picks the template.
>
>> // even though B inherits from A.

>
> Not "even though" but "because".
>
>> }
>>
>> What's the proper way making instances of B access the non-templated
>> function?

>
> Use SFINAE, make your template function non-instantiatable for any class
> that is derived from A. Utilize the 'enable_if' without making both
> functions templates. Or invent your own way. For example, use the fact
> that any class that derives from A has a member named 'A', with the same
> level of access as the base class (public if derived publicly, etc.)
>



Ok, thanks!

Before I saw your post I did a solution like this.

class SomeClass
{
public:

template<typename T>
void fnc( const T& t )
{
std::cout << "Template" << std::endl;
}

void fnc( const A& a )
{
std::cout << "Non-template" << std::endl;
}

void fnc( const B& b )
{
fnc( static_cast<const A&>( b ) );
}

};

Is it bad practice to use static_cast?

 
Reply With Quote
 
DeMarcus
Guest
Posts: n/a
 
      04-23-2010
Victor Bazarov wrote:
> DeMarcus wrote:
>> Victor Bazarov wrote:
>>> DeMarcus wrote:
>>>> Hi,
>>>>
>>>> I have a function template structure like this.
>>>>
>>>> struct A
>>>> {
>>>> };
>>>>
>>>> struct B : A
>>>> {
>>>> }
>>>>
>>>> class SomeClass
>>>> {
>>>> public:
>>>>
>>>> template<typename T>
>>>> void fnc( const T& t )
>>>> {
>>>> std::cout << "Template" << std::endl;
>>>> }
>>>>
>>>> void fnc( const A& a )
>>>> {
>>>> std::cout << "Non-template" << std::endl;
>>>> }
>>>> };
>>>>
>>>> int main()
>>>> {
>>>> SomeClass sc;
>>>> sc.fnc( A() ); // This gives me "Non-template".
>>>> sc.fnc( B() ); // Error! This gives me "Template"
>>>
>>> It's not an error. The template, since it's allowed to be
>>> instantiated, participates in the overload resolution. And because
>>> the compiler is able to deduce 'T' as 'B' (most likely), its argument
>>> conversion (reference binding, which is like the "identity") has a
>>> higher rank than the non-template's "derived-to-base" conversion.
>>> That's why the compiler picks the template.
>>>
>>>> // even though B inherits from A.
>>>
>>> Not "even though" but "because".
>>>
>>>> }
>>>>
>>>> What's the proper way making instances of B access the non-templated
>>>> function?
>>>
>>> Use SFINAE, make your template function non-instantiatable for any
>>> class that is derived from A. Utilize the 'enable_if' without making
>>> both functions templates. Or invent your own way. For example, use
>>> the fact that any class that derives from A has a member named 'A',
>>> with the same level of access as the base class (public if derived
>>> publicly, etc.)
>>>

>>
>>
>> Ok, thanks!
>>
>> Before I saw your post I did a solution like this.
>>
>> class SomeClass
>> {
>> public:
>>
>> template<typename T>
>> void fnc( const T& t )
>> {
>> std::cout << "Template" << std::endl;
>> }
>>
>> void fnc( const A& a )
>> {
>> std::cout << "Non-template" << std::endl;
>> }
>>
>> void fnc( const B& b )
>> {
>> fnc( static_cast<const A&>( b ) );
>> }
>>
>> };
>>
>> Is it bad practice to use static_cast?
>>

>
> Bad practice? No. It's fine, and it's elegant.
>


Thanks!!!

 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      04-24-2010
On 23 avr, 17:00, DeMarcus <(E-Mail Removed)> wrote:
> Hi,
>
> I have a function template structure like this.
>
> struct A
> {
>
> };
>
> struct B : A
> {
>
> }
>
> class SomeClass
> {
> public:
>
> * * template<typename T>
> * * void fnc( const T& t )
> * * {
> * * * *std::cout << "Template" << std::endl;
> * * }
>
> * * void fnc( const A& a )
> * * {
> * * * *std::cout << "Non-template" << std::endl;
> * * }
>
> };
>
> int main()
> {
> * * SomeClass sc;
> * * sc.fnc( A() ); *// This gives me "Non-template".
> * * sc.fnc( B() ); *// Error! This gives me "Template"
> * * * * * * * * * * // even though B inherits from A.
>
> }
>
> What's the proper way making instances of B access the non-templated
> function?


Another solution (apart from SFINAE) is to use a proxy class:

class SomeClass
{
public:

struct Generic
{
template<typename T>
Generic( const T& t )
{
std::cout << "Template" << std::endl;
}
};

void fnc( const Generic& g)
{
// possibly g.do_fnc(this);
}

void fnc( const A& a )
{
std::cout << "Non-template" << std::endl;
}
};

But it is not always practical.

--
Michael
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How to use the template member function of a template in the memberfunction of another template class? Peng Yu C++ 3 10-26-2008 03:51 PM
VOIP over VPN over TCP over WAP over 3G Theo Markettos UK VOIP 2 02-14-2008 03:27 PM
specialized member function takes precedence over generic template member function bluekite2000@gmail.com C++ 1 07-20-2005 08:58 PM
Re: Doesn't Take Much To Take Over A Group Soapy Digital Photography 59 09-13-2004 05:55 AM



Advertisments