Topic: which constructor should get called


Author: "Ganesh" <sgganesh@gmail.com>
Date: Tue, 30 Jan 2007 10:10:46 CST
Raw View
Consider this program:

extern "C" int printf(const char *,...);
template<class T>
struct X;

template <class T>
struct Y {
   Y(X<T>& copy) { }
};

template<class T>
struct X {
   X() { }
   X(X& copy) { printf("in cctor\n"); }

   template<class U>
   operator Y<U>() {
      printf("in operator function\n");
      return Y<U>(*this);
   }
   X(Y<T> copy) { printf("in Y<T> ctor\n");}
};

X<int>
getX() { X<int> o; return o; }

struct Container {
   Container() : container_member(getX()) { }
   X<int> container_member;
} object;

int main() { return 0; }

In this case, which constructor should the compiler resolve to of the
following options?
          1) resolve to X(X& copy) after warning the user that
reference paramter cannot be bound to an lvalue
         2) call X(Y<T> copy) after calling operator Y<U>()?

thanks!
-ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Greg Herlihy <greghe@pacbell.net>
Date: Tue, 30 Jan 2007 22:19:41 CST
Raw View


On 1/30/07 8:10 AM, in article
1170136168.163560.159240@k78g2000cwa.googlegroups.com, "Ganesh"
<sgganesh@gmail.com> wrote:

> Consider this program:
>
> extern "C" int printf(const char *,...);
> template<class T>
> struct X;
>
> template <class T>
> struct Y {
>    Y(X<T>& copy) { }
> };
>
> template<class T>
> struct X {
>    X() { }
>    X(X& copy) { printf("in cctor\n"); }
>
>    template<class U>
>    operator Y<U>() {
>       printf("in operator function\n");
>       return Y<U>(*this);
>    }
>    X(Y<T> copy) { printf("in Y<T> ctor\n");}
> };
>
> X<int>
> getX() { X<int> o; return o; }
>
> struct Container {
>    Container() : container_member(getX()) { }
>    X<int> container_member;
> } object;
>
> int main() { return 0; }
>
> In this case, which constructor should the compiler resolve to of the
> following options?
>           1) resolve to X(X& copy) after warning the user that
> reference paramter cannot be bound to an lvalue
>          2) call X(Y<T> copy) after calling operator Y<U>()?

If you had asked which behavior conforms to the C++ Standard, then the
answer would be simple: option #2. Even the compiler that follows option #1
agrees that binding an rvalue to a non-const reference is incorrect (even as
the compiler proceeds to do just that).

But since you asked what "should" the compiler do in this case - then the
answer is not so clear-cut. The question is simply: does the correctness of
the C++ compiler outweigh the correctness of the C++ programs it may
compile? In other words, is fixing the C++ compiler of paramount importance,
even if such a change would break (perhaps in silent or in subtle ways)
existing C++ programs whose correctness depends on the compiler's current,
non-compliant behavior? I think that most compiler vendors (as well as their
paying customers) would attach more value to a correct program, incorrectly
compiled than they would to an incorrect program, correctly compiled. After
all, what a C++ program actually does when run - has a far more immediate
and tangible effect on most people than what the Standard says that program
should do when run.

The current behavior of Microsoft's Visual C++ 2005 compiler no doubt
reflects a compromise between these two sets of competing priorities. VC++
2005 still binds the rvalue to the non-const reference (at least for the
time being), but warns the user that its behavior is not conforming. So if
the user dismisses the warning and takes no action, the program's existing
behavior is preserved (but should that behavior change in the future - at
least the user had been warned). Moreover, this warning helps developers
avoid creating dependencies in their code on this non-conforming compiler
behavior.

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "=?iso-8859-1?q?Daniel_Kr=FCgler?=" <daniel.kruegler@googlemail.com>
Date: Wed, 31 Jan 2007 11:47:08 CST
Raw View
> The current behavior of Microsoft's Visual C++ 2005 compiler no doubt
> reflects a compromise between these two sets of competing priorities. VC++
> 2005 still binds the rvalue to the non-const reference (at least for the
> time being), but warns the user that its behavior is not conforming. So if
> the user dismisses the warning and takes no action, the program's existing
> behavior is preserved (but should that behavior change in the future - at
> least the user had been warned). Moreover, this warning helps developers
> avoid creating dependencies in their code on this non-conforming compiler
> behavior.

I tried yesterday night VS-2005 SP1 and it correctly deduced #2.

Greetings from Bremen,

Daniel Kr   gler


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]