Different forms of copy constructor
-
daddy_felix schrieb:
In your second, you use the assignment operator.
Actually, he does not. Both forms are nearly the same except that the second form (the one with the
requires the copy-constructor to be available. Not shure why the Compiler complains the first but not the second form, though. The error message suggest there is no straight conversion between cv::Point2fandcv::Point2d, but the latter seems to be a typedef forcv::Point_<double>. Did you try looking in the opencv manual/forums for such cases of ambuguity?
-
This looks like cv::Point2f simply has too many conversion constructors/operators.
In
int main(void) { cv::Point2f a; //Point consists of 2 floats cv::Point2d b(a); //Point consists of 2 doubles. ERROR HERE return 0; }b ist initialized directly with a. This tells the compiler to enumerate all constructors of cv::Point2d that could possibly be called (by suitably converting the argument a to something that constructor can take). Overload resolution then looks at how these conversion-sequences rank with respect to each other and chooses the constructor with the best ranking conversion sequence. However, user-defined conversion sequences (those that involve a constructor or conversion operator call) usually rank the same because they are ranked based on the conversion needed after calling the conversion constructor/operator. Since the enumerated constructor probably take their arguments by reference, that 2nd conversion is most likely either the identity conversion or a qualification conversion, making them undistinguishable, resulting in an ambiguous call.
in short: consider all possibly conversions that produce something a constructor of cv::Point2d can take, use the best conversion sequence found.
int main(void) { cv::Point2f a; //Point consists of 2 floats cv::Point2d b = a; //Point consists of 2 doubles. No error here. return 0; }This is a case of copy initialization. Copy initialization requires the right hand side to be of the same type as the object to initialized. If thats not the case, that argument is converted and the result of the conversion is used to directly initialize the object in question (since the types are the same, this usually means calling the copy or move constructor).
in short: convert to the target type, then initialize directly with the conversion result.
Since this only considers all possible conversion sequences to cv::Point2d, not to any other types cv::Point2d might have a constructor for, this appears to work.
afaik visual c++ (unless severly outdated) and g++ both usually get this part right.
template<typename _Tp> class CV_EXPORTS Point_ { public: typedef _Tp value_type; // various constructors Point_(); Point_(_Tp _x, _Tp _y); Point_(const Point_& pt); Point_(const CvPoint& pt); Point_(const CvPoint2D32f& pt); Point_(const Size_<_Tp>& sz); Point_(const Vec<_Tp, 2>& v); Point_& operator = (const Point_& pt); //! conversion to another data type template<typename _Tp2> operator Point_<_Tp2>() const; //! conversion to the old-style C structures operator CvPoint() const; operator CvPoint2D32f() const; operator Vec<_Tp, 2>() const; //! dot product _Tp dot(const Point_& pt) const; //! dot product computed in double-precision arithmetics double ddot(const Point_& pt) const; //! checks whether the point is inside the specified rectangle bool inside(const Rect_<_Tp>& r) const; _Tp x, y; //< the point coordinates };...
looks like a design error://! conversion to another data type template<typename _Tp2> operator Point_<_Tp2>() const;if that were a conversion constructor instead, there would be no problem.
So g++ is doing the right thing, and either visual c++ in error or using a different source.
There's more actually, since we have both conversion constructors and operators for some types, using copy-initialization will be ambiguous, while direct initialization is not:
CvPoint a; Point_<double> b(a); // ok, calls conversion constructor Point_<double> c = a; // ambiguous, conversion by constructor or operatorLooks like this code didn't receive much testing.
As a rule of thumb you never want to have both conversion constructors and operators in the same class (template), esp. not for the same types (sometimes it's unavoidable, but then there's explicit, too).
-
camper, thank you for detailed explanation. I was suspecting something like that.
Here is interesting example:
#include <iostream> struct MyInt { int x; MyInt(int const y): x( y ) { std::cout << "Constructor 1 called." << std::endl; } MyInt(MyInt const &y): x( y.x ) { std::cout << "Constructor 2 called." << std::endl; } }; int main(void) { MyInt i = 1; return 0; }GCC output:
Constructor 1 called. Constructor 2 called.Visual Studio output:
Constructor 1 called.As you can see, Visual Studio is better, but GCC is more correct.
-
SAn schrieb:
As you can see, Visual Studio is better, but GCC is more correct.
AFAIK, both are correct. For copy-initialization, the Copy-Ctor has to be available, but does not ned to be called i.e. may be omitted completely.
-
New information from
man g++:-fno-elide-constructors The C++ standard allows an implementation to omit creating a temporary which is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.So, the following behavior is standard compliant?
#include <iostream> class MyInt { private: int x; public: MyInt(int const y): x( y ) { std::cout << "Constructor 1 called." << std::endl; } MyInt(MyInt const &y): x( y.x ) { std::cout << "Constructor 2 called." << std::endl; } }; int main(void) { MyInt i = 1; return 0; }Output:
Constructor 1 called.
-
yes
-
SAn schrieb:
So, the following behavior is standard compliant?
Why shouldn't it be? Thats simply another form of calling the corresponding ctor, known as "copy initialisation". pumuckl already explained it pretty well.
And btw: I dare you to say, VC++ is nearly as good as GCC is

-
#include <iostream> struct MyInt { int x; MyInt(int const y): x( y ) { std::cout << "Constructor 1 called." << std::endl; } MyInt(MyInt const &y): x( y.x ) { std::cout << "Constructor 2 called." << std::endl; } }; int main() { /* So, what's going on there? In fact it is not that complicated: 1) A instance, named 'i', shall be created. 2) The right operand of the assignment operator is a literal of type 'int', thus your struct 'MyInt' must have a constructor looking like 'MyInt(int)'. 3) Well done, your struct 'MyInt' does have a constructor looking like 'MyInt(int)', thus the compiler is happy. 4) a) The constructor 'MyInt(int)' is called, creating a temporary. ( like 'MyInt tmp(1);' ) In theory: b) That created temporary serves as argument for the copy constructor 'MyInt(MyInt const&)'. c) The copy constructor receives that temporary. d) The copy constructor is now capable of initializing the actual instance 'i' with the aid of that temporary. --> Finally two instances were created, the temporary and 'i'. --> And to be more precise, that two instances are equivalent. --> Kinda stupid and absolutely unnecessary, isn't it? In practice: b) The copy constructor 'MyInt(MyInt const&)' is not called. The constructor 'MyInt(int)' is the only constructor being called. c) As a consequence, the instance created by 'MyInt(int)' is no temporary but the actual instance 'i'. --> Finally only one instance was created, namely 'i'. --> That's pretty cool, isn't it? --> NOTE: The theoretical process must be feasible (compilable), otherwise the practical process can't be done. What I'm trying to say is, you will get a compiler error, if the copy constructor is not public. */ MyInt i = 1; }
-
<scnr>
Sone darf jetzt noch etwas lernen.
Sone schrieb:
I dare you to say, VC++ is nearly as good as GCC is

Meinst du nicht, dass sich dieser Satz etwas merkwürdig anhört? Was du eigentlich sagen wolltest ist:
Don't you dare say (kein Gerund) VC++ is nearly as good as GCC.Sone schrieb:
pumuckl already explained it pretty well.
Im Allgemeinen ist die Regel korrekt (wie in diesem Fall): Wenn sich das Adjektiv auf ein Verb bezieht, musst du das Adverb nehmen. Es gibt aber auch Ausnahmen, wie z.B.
you look beautiful
sleep good
sleep tight
it smells good
...
Wann es eine Ausnahme ist und wann nicht, keine Ahnung ob es da eine Regel gibt, das lernt man aber automatisch, wenn man sich mit Englisch beschäftigt.Und noch eine Information:
wellist sowohl Adverb als auch Adjektiv. Sprich du kannst sagenI am welloderI am good. Beides ist korrekt, bedeutet aber nich dasselbe. Mittelswellbeziehst du dich auf deine körperliche Gesundheit und mittelsgoodsagst du, wie es dir gerade emotional geht (also psychisch), z.B. wenn du sagen willst, dass du gerade glücklich bist.Lustig wirds auch bei
tightundtightly, das darst du aber selbst nachschlagen.

</scnr>
-
HaHa

Sone schrieb:
I dare you to say, VC++ is nearly as good as GCC is

Meinst du nicht, dass sich dieser Satz etwas merkwürdig anhört? Was du eigentlich sagen wolltest ist:
Don't you dare say (kein Gerund) VC++ is nearly as good as GCC.Nö, eigentlich sollte nach dare doch ein 'to'. Zumindest sagt es so mein Freund, und der ist 10 Jahre lang in Florida aufgewachsen... und spricht immer noch mehr Englisch als Deutsch... KA

Sone schrieb:
pumuckl already explained it pretty well.
Im Allgemeinen ist die Regel korrekt (wie in diesem Fall): Wenn sich das Adjektiv auf ein Verb bezieht, musst du das Adverb nehmen. Es gibt aber auch Ausnahmen, wie z.B.
you look beautiful
sleep good
sleep tight
it smells good
...
Wann es eine Ausnahme ist und wann nicht, keine Ahnung ob es da eine Regel gibt, das lernt man aber automatisch, wenn man sich mit Englisch beschäftigt.Und noch eine Information:
wellist sowohl Adverb als auch Adjektiv. Sprich du kannst sagenI am welloderI am good. Beides ist korrekt, bedeutet aber nich dasselbe. Mittelswellbeziehst du dich auf deine körperliche Gesundheit und mittelsgoodsagst du, wie es dir gerade emotional geht (also psychisch), z.B. wenn du sagen willst, dass du gerade glücklich bist.Lustig wirds auch bei
tightundtightly, das darst du aber selbst nachschlagen.

</scnr>Haha

Glaub mir, ich spreche sehr viel Englisch. Und bei mir kommt son Satz einfach rausgeschossen, ich denke gar nicht drüber nach. Es hört (und "fühlt") sich einfach richtig an...
-
Sone schrieb:
Nö, eigentlich sollte nach dare doch ein 'to'. Zumindest sagt es so mein Freund, und der ist 10 Jahre lang in Florida aufgewachsen... und spricht immer noch mehr Englisch als Deutsch... KA

Nö, da kommt kein
to. Ich hab auch schon Leute getroffen, die seit 10 Jahren in Deutschland leben und kein deutsch können.
edit: Ah ok, man kann eintosetzen, muss es aber nicht. Ich habe aber mal noch nie jemanden gehört, der da eintobenutzt.Sone schrieb:
bei mir kommt son Satz einfach rausgeschossen, ich denke gar nicht drüber nach. Es hört (und "fühlt") sich einfach richtig an...
Dein Abi Lehrer wird dir was husten.

-
Gugelmoser schrieb:
Sone schrieb:
bei mir kommt son Satz einfach rausgeschossen, ich denke gar nicht drüber nach. Es hört (und "fühlt") sich einfach richtig an...
Dein Abi Lehrer wird dir was husten.

Genau so hat mir das mein Mathe-Lehrer auch gesagt, als ich ihm so einen dirty hack vorgeführt habe, mit dem ich mir vor einem Jahr oder so Polynom-Division vereinfachen wollte
