473,396 Members | 1,755 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

template & specialization

I am trying to write two constructors for the same class. One takes an
iterator and so is a template. The other takes a particular type by
reference to const.

class Foo {
public:
template<typename InputIterator>
Foo(InputIterator i);
Foo(const Bar & b);

When I do this, trying to construct a Foo from a Bar calls the
template, not the constructor from a Bar. This is in VC++ 7.0. And it
does not matter which I declare first.

Questions: Is this a compiler oddity or standard behavior? Is there any
way around it?

I know a semi-solution. When I pass them both by value or both by
reference to const, it works.

template<typename InputIterator>
Foo(InputIterator i);
Foo(Bar b);

or

template<typename InputIterator>
Foo(const InputIterator & i);
Foo(const Bar & b);

But I would prefer not to do that. Any other ideas/thoughts?

May 4 '06 #1
2 1836
Glenn G. Chappell wrote:
I am trying to write two constructors for the same class. One takes an
iterator and so is a template. The other takes a particular type by
reference to const.

class Foo {
public:
template<typename InputIterator>
Foo(InputIterator i);
Foo(const Bar & b);

When I do this, trying to construct a Foo from a Bar calls the
template, not the constructor from a Bar. This is in VC++ 7.0. And it
does not matter which I declare first.

Questions: Is this a compiler oddity or standard behavior? Is there
any way around it?
It is a standard behaviour. If you construct from an object, the template
one will win because the compiler will figure out what type it is from
the argument and there will be no conversion required. A const reference
requires "binding to".
I know a semi-solution. When I pass them both by value or both by
reference to const, it works.

template<typename InputIterator>
Foo(InputIterator i);
Foo(Bar b);

or

template<typename InputIterator>
Foo(const InputIterator & i);
Foo(const Bar & b);

But I would prefer not to do that. Any other ideas/thoughts?


You can add a fake argument to the one you don't care to keep implicit:

template<typename InputIterator>
Foo(InputIterator i, int);

Of course, you will have to stick an extra argument when constructing
an object from the iterator...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 4 '06 #2
* Glenn G. Chappell:
I am trying to write two constructors for the same class. One takes an
iterator and so is a template. The other takes a particular type by
reference to const.

class Foo {
public:
template<typename InputIterator>
Foo(InputIterator i);
Foo(const Bar & b);

When I do this, trying to construct a Foo from a Bar calls the
template, not the constructor from a Bar. This is in VC++ 7.0. And it
does not matter which I declare first.
With both MSVC 7.1 and MingW g++ 3.4.2, the following program,

#include <iostream> // std::cout
#include <ostream> // operator<<, std::endl

void say( char const s[] ) { std::cout << s << std::endl; }

class Bar {};

class Foo
{
public:
template< typename InputIterator >
Foo( InputIterator ) { say( "Template" ); }

Foo( Bar const& ) { say( "Non-template" ); }
};

int main()
{
Bar b;
Foo f( b );
}

says "Non-template", but when passed an argument of type derived from
Bar it says "Template".

Questions: Is this a compiler oddity or standard behavior?
Off-hand I'd say a compiler oddity for the case of pure Bar argument.

Is there any way around it?
Best, use the solution you outline below. Second best (but should be
done anyway), upgrade the compiler. Third, perhaps use SFINAE
(Substitution Failure Is Not An Error).

The Boost library has a ready-made SFINAE solution. The following might
give you an idea if you don't want to use Boost:

#include <iostream> // std::cout
#include <ostream> // operator<<, std::endl

void say( char const s[] ) { std::cout << s << std::endl; }

class Bar {};
class BarD: public Bar {};

template< typename InputIterator >
struct NonBar { typedef InputIterator T; };

template<> struct NonBar<Bar>;
template<> struct NonBar<BarD>;

class Foo
{
public:
template< typename InputIterator >
Foo( InputIterator, typename NonBar<InputIterator>::T* = 0 )
{ say( "Template" ); }

Foo( Bar const& ) { say( "Non-template" ); }
};

int main()
{
Bar b;
BarD bd;

Foo f( b );
Foo fd( bd );
Foo fi( 666 );
}

with output "Non-template, non-template, template" with both MSVC 7.1
and MingW g++ 3.4.2.

Of course to make it more general you'd have to check sub-subclass
relationship and somehow make that part of the SFINAE checking (not sure
whether that's possible, perhaps the Boost solution does that), and
anyway, as I wrote above, consider solutions (1) and (2) first.

Solution (1):

I know a semi-solution. When I pass them both by value or both by
reference to const, it works.

template<typename InputIterator>
Foo(InputIterator i);
Foo(Bar b);

or

template<typename InputIterator>
Foo(const InputIterator & i);
Foo(const Bar & b);

But I would prefer not to do that. Any other ideas/thoughts?


I think this is the cleanest solution.

Why do you want to avoid this?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 4 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Paul MG | last post by:
Hi Template partial specialization always seems like a fairly straightforward concept - until I try to do it :). I am trying to implement the input sequence type (from Stroustrup section...
2
by: SainTiss | last post by:
Hi, If you've got a template class with lots of methods, and then you've got a type which works with the template, except for one method... What you need to do there is specialize the...
8
by: Agent Mulder | last post by:
Hi group, I have a problem with partial template specialization. In the code below I have a template struct Music with one method, play(), and three kinds of music, Jazz, Funk and Bach. When I...
2
by: Jeff | last post by:
/* -------------------------------------------------------------------------- Hello, I was experimenting with class templates and specializing member functions and came across a simple problem...
3
by: Nathanael D. Noblet | last post by:
Hello, I'm having a problem with a templated class. I have two template classes Node and List. Everything works fine when the type for List is an object and not a pointer ie:"List<Object>...
6
by: Dave | last post by:
Hello all, Consider this function template definition: template<typename T> void foo(T) {} If foo is never called, this template will never be instantiated. Now consider this explicit...
6
by: NKOBAYE027 | last post by:
FIRST POST Hi All: I'm trying to write a simple specialization before moving on to something a bit more complex - always a good idea in my case, at least. :o) I'm trying to adapt the example...
9
by: Marek Vondrak | last post by:
Hello. I have written the following program and am curious why it prints "1" "2". What are the exact effects of explicitly providing function template parameters at the call? Is the second...
2
by: Barry | last post by:
The following code compiles with VC8 but fails to compiles with Comeau online, I locate the standard here: An explicit specialization of any of the following:
6
by: abir | last post by:
i have a template as shown template<typename Sclass Indexer{}; i want to have a specialization for std::vector both const & non const version. template<typename T,typename Aclass...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.