Lack of respect for an explicit constructor?

D

Dave Theese

Hello again,

In the program below, the following line is of interest:

bar.insert(make_pair(42, 17));

insert() expects a pair<foo<1>, foo<2> >. I'm giving it a pair <int, int>.
But this is OK because there is an implicit conversion in pair that allows
this:

// This is in the definition of pair; it is a member template that happens
to be a constructor.
template<class U, class V> pair(const pair<U, V> &p);

This will allow conversion from pair<int, int> to pair<foo<1>, foo<2> >.
But it seems that we should now run into a problem...

Each member of the pair has to, in turn, undergo an implicit conversion.
Specifically int to foo<1> and int to foo<2>. How is it that this is
working (VC++ 6.0 and g++)? My constructor in foo that takes an int is
explicit!!! Can anyone shed light on how this compiles and runs as if the
constructor were not explicit?

Thanks,
Dave

P.S. WW: Thanks for clarifying my earlier ridiculous mistake!!!



#ifdef WIN32
#pragma warning(disable: 4786)
#endif

#include <iostream>
#include <map>

using namespace std;

template <int type_differentiator>
class foo
{
public:
explicit foo(int d): data(d)
{
cout << "foo<"
<< type_differentiator
<< ">(int) : "
<< data
<< endl;
}

foo(const foo &f): data(f.data)
{
cout << "foo<"
<< type_differentiator
<< ">(const foo &): "
<< data
<< endl;
}

~foo()
{
cout << "~foo<"
<< type_differentiator
<< ">() : "
<< data
<< endl;
}

bool operator<(const foo &lhs) const {return data < lhs.data;}

private:
int data;
};

int main()
{
map<foo<1>, foo<2> > bar;

cout << "Starting..." << endl;

// Question: How does the line below compile? foo's constructor is
explicit!
bar.insert(make_pair(42, 17));

// bar.insert(make_pair(foo<1>(43), foo<2>(18)));

cout << "Exiting..." << endl;

return 0;
}
 
A

Attila Feher

Dave said:
Hello again,

In the program below, the following line is of interest:

bar.insert(make_pair(42, 17));

insert() expects a pair<foo<1>, foo<2> >. I'm giving it a pair <int,
int>. But this is OK because there is an implicit conversion in pair
that allows this:

// This is in the definition of pair; it is a member template that
happens to be a constructor.
template<class U, class V> pair(const pair<U, V> &p); [SNIP]
// Question: How does the line below compile? foo's constructor is
explicit!
bar.insert(make_pair(42, 17));
[SNIP]

Post the source of that templated constructor. Without that there is no way
to tell what is going on since it is in there, whatever is going on. For
example you using explicit syntax to make that foo<1> and foo<2>.
 
R

Rob Williscroft

Dave Theese wrote in
Each member of the pair has to, in turn, undergo an implicit
conversion. Specifically int to foo<1> and int to foo<2>. How is it
that this is working (VC++ 6.0 and g++)? My constructor in foo that
takes an int is explicit!!! Can anyone shed light on how this
compiles and runs as if the constructor were not explicit?

Because the template constructor initializes explicitly
i.e:

#include <iostream>

struct X
{
int x;
explicit X( int xx ) : x( xx )
{
std::cerr << "explicit X::X\n";
}
};

template < typename F >
struct single
{
F only;
single( F const &rhs ) : only( rhs ) {}
template < typename U >
single( single< U > const &rhs ) : only( rhs.only )
{
std::cerr << "template single::single\n";
}
};

int main()
{
single< int > si( 1 );

std::cerr << "X ...\n";
single< X > sx( si );
}

Note the line: single( single< U > const &rhs ) : only( rhs.only )
and especialy the only( rhs.only ) whitch is the explicit
initialization.

HTH

Rob.
 

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,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top