Computing.Net > Forums > Programming > C++ Template problem

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

C++ Template problem

Reply to Message Icon

Name: Chris
Date: June 23, 2002 at 09:36:44 Pacific
Comment:

Ok, well I tried posting my code using this but for some reason the HTML wouldn't let me just paste plain text with no HTML formatting (it thought some of the code commands were HTML commands, which they were not intended to be)

Anyway, my code is at:
http://www.enisoc.com/~cpp/pastebin/?181

But change the last line to bar(b) instead of bar(a).

Anyway, my problem is this program output is:

foo
normal

I want it to be:

foo
baz

The compiler creates a generic template that uses class type B instead of converting B to an A reference and using the specialization, like I want it to. Both conversions are valid, but the compiler thinks the one it created from the generic template is "better" so it uses that instead. Is there a way to override this default behavior and make it use my specialization?

Thanks for any ideas.



Sponsored Link
Ads by Google

Response Number 1
Name: Jeff J
Date: June 23, 2002 at 13:06:53 Pacific
Reply:

Finally, a template question! I am sharing your pain here, more than you know. I love specialisations, but they have driven me crazy on jobs where I can't choose the compiler. Borland's bcc (v4.0 or higher) is the best I have ever used (fully ANSI compliant), and gcc comes real close. Micro$oft's is almost anti-templates. I don't even bother trying to do specialisations in VC++ anymore, lest I go bald from aggravation. Even if you have VS.Net, they're still not compliant enough.

So first, what compiler are you using?



0

Response Number 2
Name: cup
Date: June 23, 2002 at 15:37:50 Pacific
Reply:

In your posted program, the second call should be

bar(b)

to produce normal. To produce baz use

bar((A&) b)

Jeff J might have a more elegant solution. I'm quite pedestrian when it comes to templates.


0

Response Number 3
Name: Jeff J
Date: June 23, 2002 at 16:52:13 Pacific
Reply:

cup is absolutely right. I'm afraid I spent too little time analysing the code, while waiting to see what compiler you're using. The specialisation you currently have, has no built-in feature to cast a B to an A [reference]. Since it requires an A (or A ref), it won't take anything that looks like a B. Thus, casting b to an A ref is the solution to what you want.

The only other thing I can think of, is to add yet another specialisation, though that's not what you requested:

template<> void bar(B& y) {
y.foo();
}

That will allow bar(b) to produce the desired result, just not with your current specialisation. I should have deduced from your post, that function specialisations must work on your compiler.


0

Response Number 4
Name: Chris
Date: June 24, 2002 at 09:50:33 Pacific
Reply:

I'm using M$ VC++ 6.0

I want the compiler to do the conversion automatically. I thought of doing:

bar((A&)B);

However, I can't "specialize" the call, just the template. Is there a way in the ANSI standard (assuming my compiler is fully compliant - I know it isn't) to do what I want?


0

Response Number 5
Name: Jeff J
Date: June 25, 2002 at 08:01:59 Pacific
Reply:

Perhaps I'm misunderstanding your post, but C++ is all about very strong type checking, which is virtually contrary to the idea of automatic (implicit) conversions. In fact, the C-style casts we generally still use (they're much more terse), such as posted here, were originally intended to be removed from C++. The ISO/ANSI equivalents are static_cast, dynamic_cast, reinterpret_cast, and const_cast. Those names are in a very inconvenient long-style, which is why they never gained favour, but their incorporation underscores how important type checking is. The C subset of C++ is sometimes referred to as "C with better type checking" for good reason.

As it is, function templates (unlike class templates, which are far more complex) tend to be controversial because they are so implicit already (they came about early in C++), as opposed to explicit class templates (where class specialisations are the tough ones). That we're even able to write lines like

bar(a);

instead of

bar < A &> (a);

came about due to heated committee debates over convenience.

Function specialisations, much like regular C++ overloads, require the compiler to choose the closest match for a given call. Thus, if "specific" type A is passed, the compiler will try to find a specialisation that takes a type A. If it cannot, it will default to the generic implementation (type T in your case). If you pass a type B, then if no specialisation that takes a type B is found, the compiler will default to the generic (which it does). This is implicit calling, as the compiler is expected to make the choice.

I'm interpreting that you'd like to be able to call bar(b), have the compiler automatically cast from an object of derived class B, down to the base class A (and pass just a reference of course). The function specialisation you wish to be called specifies a type A (by reference). Then since the seemingly object A is really an object of derived type B, the virtual function bar should be called as specified in B. I guess I'm getting confused as to why you would need to go from a B to an A, and then from the A to a function specified in B, when the original object was already a B. So I'll just do what I do best: continue on ad nauseum...

The only ways I'm aware of to coerce the compiler, are to either have a specialisation expect a type B (as in my last post), or trick the compiler by casting to an A (as in cup's post). Both methods are explicit, but either way the object will still be of type B, as declared. I guess you could twiddle with RTTI, but that's usually not necessary, especially when dynamic_cast is available. Better ANSI compilance won't help here; this is within VC++'s capabilites. Of course, it's entirely possible I am missing something in the goal here, or another alternative is not coming to mind, but then I don't know why this end needs to be achieved.


0

Related Posts

See More



Response Number 6
Name: Jeff J
Date: June 25, 2002 at 08:14:24 Pacific
Reply:

Would a "wrapper" specialisation be usable? How about

template ; bar(B& y)
{
bar((A&)y);
}

You'd still need to add a second specialisation, but it would simply call your first specialisation. Inlining it would reduce any overhead.


0

Response Number 7
Name: Jeff J
Date: June 25, 2002 at 08:18:47 Pacific
Reply:

The old ampersand+lt+semicolon didn't work on that one, it should have been:

template <> bar(B& y)


0

Response Number 8
Name: Jeff J
Date: June 25, 2002 at 08:24:35 Pacific
Reply:

To keep in mind about posting here:

An ampersand+lt+semicolon followed by an ampersand+gt+semicolon does not work. Nor does using the former within double quotes. I suspect custom text parsing at work, not just pure HTML.


0

Sponsored Link
Ads by Google
Reply to Message Icon

s video tv out,, Removing Adaptec EasyCD C...



Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Programming Forum Home


Sponsored links

Ads by Google


Results for: C++ Template problem

C++ template problem (2nd post) www.computing.net/answers/programming/c-template-problem-2nd-post/2209.html

simple C++ compile problem in Linux www.computing.net/answers/programming/simple-c-compile-problem-in-linux-/1282.html

C++ Homework problem www.computing.net/answers/programming/c-homework-problem/8556.html