From: 3DCoderGuy on
"Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message
news:udZOD8LsIHA.4848(a)TK2MSFTNGP05.phx.gbl...
> And, by the way, you want the operator== to be const. Not returning const
> bool, which doesn't make sense.
>
> bool operator==(const XYZ_POINT<T> &xyzTest) const;
>
> "3DCoderGuy" <nobody(a)nospam.com> wrote in message
> news:uzopyzJsIHA.4476(a)TK2MSFTNGP06.phx.gbl...
>> This is my XYZ_POINT.h file
>>
>> template<typename T>
>> class XYZ_POINT
>> {
>> private:
>> T x;
>> T y;
>> T z;
>> public:
>> XYZ_POINT(void) {};
>> XYZ_POINT(const T allVals) : x(allVals), y(allVals), z(allVals) {};
>> bool const operator==(const XYZ_POINT<T> &xyzTest);
>> }
>>
>> In my cpp file I have this.
>> template<typename T>
>> bool const XYZ_POINT<T>::operator ==(const XYZ_POINT<T> &xyzTest)
>> {
>> return ((x == xyzTest.GetX()) &&(y == xyzTest.GetY()) &&(z ==
>> xyzTest.GetZ()));
>> }
>>
>> In the main file I have this
>>
>> int _tmain(int arc, _TCHAR* argv[])
>> {
>> XYZ_POINT<double> dXYZPnt1(1,0,0);
>> XYZ_POINT<double> dXYZPnt2(3,0,0);
>>
>> if (dXYZPnt1 == dXYZPnt2)
>> {
>> bool b = true;
>> b = false;
>> }
>> }
>>
>> Doesn't compile with the following error
>> error LNK2019: unresolved external symbol "public: bool const __thiscall
>> XYZ_POINT<double>::operator==(class XYZ_POINT<double> const &)"
>> (??8?$XYZ_POINT@N@@QAE?B_NABV0@@Z) referenced in function _main
>>
>> If I move the implimentation to the header file it compiles fine.
>>
>> What am I doing wrong?
>>
>> The actual implimentation is more complex then I'm demonstrating and I
>> need to include some header files that I don't want in the declaration.
>>
>> Thanks
>>
>> Mark
>>
>>
>
>

Thanks Alexander for your reply.
The use of const on the return comes from Scott Meyers' Effective C++ Third
Edition Item 3
"const Rational operator*(const Rational& lhs, const Rational& rhs);
Many programmers squint when they first see this. Why should the result of
operator* be a const object? Because if it weren't, clents would be able to
commit atrocities like this:
Rational a, b, c;
....
(a * b) = c; // invoke operator= on the result of a*b!
...."

You might not see that example as typed but if( a * b = c) ... does occure
because of typing mistakes. The compiler will catch this.

Now this might not apply to the operator== but it is a practice I've picked
up and just haven't changed.

Thanks again
Mark


From: Ben Voigt [C++ MVP] on
> Thanks Alexander for your reply.
> The use of const on the return comes from Scott Meyers' Effective C++
> Third Edition Item 3
> "const Rational operator*(const Rational& lhs, const Rational& rhs);
> Many programmers squint when they first see this. Why should the
> result of operator* be a const object? Because if it weren't, clents
> would be able to commit atrocities like this:
> Rational a, b, c;
> ...
> (a * b) = c; // invoke operator= on the result of a*b!
> ..."
>
> You might not see that example as typed but if( a * b = c) ... does
> occure because of typing mistakes. The compiler will catch this.
>
> Now this might not apply to the operator== but it is a practice I've
> picked up and just haven't changed.

Good enough. It's not that const in the return type is wrong -- it
certainly isn't, and Scott makes a very good argument for including it -- it
just isn't necessary for correct usage of the operator to work. On the
other hand making the function const is necessary, otherwise the compiler
will throw errors when you test for equality with a const reference.

>
> Thanks again
> Mark


From: 3DCoderGuy on
"Alf P. Steinbach" <alfps(a)start.no> wrote in message
news:M7OdndGUCJ4azb_VnZ2dnUVZ_oqhnZ2d(a)comnet...
>* 3DCoderGuy:
>> This is my XYZ_POINT.h file
>>
>> template<typename T>
>> class XYZ_POINT
>> {
>> private:
>> T x;
>> T y;
>> T z;
>> public:
>> XYZ_POINT(void) {};
>> XYZ_POINT(const T allVals) : x(allVals), y(allVals), z(allVals) {};
>> bool const operator==(const XYZ_POINT<T> &xyzTest);
>> }
>>
>> In my cpp file I have this.
>> template<typename T>
>> bool const XYZ_POINT<T>::operator ==(const XYZ_POINT<T> &xyzTest)
>> {
>> return ((x == xyzTest.GetX()) &&(y == xyzTest.GetY()) &&(z ==
>> xyzTest.GetZ()));
>> }
>>
>> In the main file I have this
>>
>> int _tmain(int arc, _TCHAR* argv[])
>> {
>> XYZ_POINT<double> dXYZPnt1(1,0,0);
>> XYZ_POINT<double> dXYZPnt2(3,0,0);
>>
>> if (dXYZPnt1 == dXYZPnt2)
>> {
>> bool b = true;
>> b = false;
>> }
>> }
>>
>> Doesn't compile with the following error
>> error LNK2019: unresolved external symbol "public: bool const __thiscall
>> XYZ_POINT<double>::operator==(class XYZ_POINT<double> const &)"
>> (??8?$XYZ_POINT@N@@QAE?B_NABV0@@Z) referenced in function _main
>>
>> If I move the implimentation to the header file it compiles fine.
>>
>> What am I doing wrong?
>
> Quite a lot. But to answer directly what you're probably most interested
> in, see
>
> <http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12>.
>
> It's very often a good idea to check the C++ FAQ before asking.
>
> Now as to other wrongdoings.
>
> The class name XYZ_POINT, in all uppercase, is an invitation to name
> clashes with macros, and besides it hurts the eyes and ears (all uppercase
> is perceived as shouting and is visually distracting). Preferentially
> reserve all uppercase names for macros, and make sure that your own macros
> are always defined with all uppercase names. That way you minimize the
> chance of macro name clashes.
>
> Using 'void' to indicate "no arguments": this is a C-ism, not meaningful
> in C++.
>
> Declaring and defining a default constructor that does not initialize the
> members: they will have arbitrary (formally invalid) values.
>
> Semicolon after closing '}' of function definition.
>
> Defining a copy constructor when the one you get by default is just fine.
>
> Not defining operator<, which is the one you really need for algorithms,
> containers etc.
>
> Missing semicolon after closing '}' of class definition.
>
> "int _tmain(int arc, _TCHAR* argv[])". This is something some Microsoft
> employee scooped up from drainage system and it smelled so bad that all
> her co-workers just loved it, and even though they failed to find any
> reasonable use for it they just added it everywhere, luv it luv it.
> Standard for what you need here is "int main()".
>
> Style: "if( something ) { assign to boolean }". Instead do "boolean =
> something". I'm assuming the intent was not to have the boolean as a
> local variable.
>
>
>> The actual implimentation is more complex then I'm demonstrating and I
>> need to include some header files that I don't want in the declaration.
>
> When you fix your "main" the above code does not need any headers.
>
>
> Cheers, & hth.,
>
> - Alf
>
>
> --
> 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?

It is amazing how you can google for something and get a million hits but
not the right one. I now have a bookmark to the C++ Faq Lite page.

I always make an effort to do my research first and then ask the groups. I
just wasn't finding the answer, which led me to ask the group. I respect
the fact that another developer has to give of their time to read and answer
my question.

That is always greatly appreciated.



One comment on the C-ism of f(void), your right it is a C-ism. At least I
broke my self of f(a,b) int b, int a;{}.

Now I need to decide if I'm on the void *p = NULL; or void *p = 0; camps.



Thanks Alf

Mark



P.S. I even do research on those who reply to me. You are a great
contributor to the groups, thanks.


From: Alf P. Steinbach on
* 3DCoderGuy:
> "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message
> news:udZOD8LsIHA.4848(a)TK2MSFTNGP05.phx.gbl...
>> And, by the way, you want the operator== to be const. Not returning const
>> bool, which doesn't make sense.
>>
>> bool operator==(const XYZ_POINT<T> &xyzTest) const;
>>
>> "3DCoderGuy" <nobody(a)nospam.com> wrote in message
>> news:uzopyzJsIHA.4476(a)TK2MSFTNGP06.phx.gbl...
>>> This is my XYZ_POINT.h file
>>>
>>> template<typename T>
>>> class XYZ_POINT
>>> {
>>> private:
>>> T x;
>>> T y;
>>> T z;
>>> public:
>>> XYZ_POINT(void) {};
>>> XYZ_POINT(const T allVals) : x(allVals), y(allVals), z(allVals) {};
>>> bool const operator==(const XYZ_POINT<T> &xyzTest);
>>> }
>>>
>>> In my cpp file I have this.
>>> template<typename T>
>>> bool const XYZ_POINT<T>::operator ==(const XYZ_POINT<T> &xyzTest)
>>> {
>>> return ((x == xyzTest.GetX()) &&(y == xyzTest.GetY()) &&(z ==
>>> xyzTest.GetZ()));
>>> }
>>>
>>> In the main file I have this
>>>
>>> int _tmain(int arc, _TCHAR* argv[])
>>> {
>>> XYZ_POINT<double> dXYZPnt1(1,0,0);
>>> XYZ_POINT<double> dXYZPnt2(3,0,0);
>>>
>>> if (dXYZPnt1 == dXYZPnt2)
>>> {
>>> bool b = true;
>>> b = false;
>>> }
>>> }
>>>
>>> Doesn't compile with the following error
>>> error LNK2019: unresolved external symbol "public: bool const __thiscall
>>> XYZ_POINT<double>::operator==(class XYZ_POINT<double> const &)"
>>> (??8?$XYZ_POINT@N@@QAE?B_NABV0@@Z) referenced in function _main
>>>
>>> If I move the implimentation to the header file it compiles fine.
>>>
>>> What am I doing wrong?
>>>
>>> The actual implimentation is more complex then I'm demonstrating and I
>>> need to include some header files that I don't want in the declaration.
>>>
>>> Thanks
>>>
>>> Mark
>>>
>>>
>>
>
> Thanks Alexander for your reply.
> The use of const on the return comes from Scott Meyers' Effective C++ Third
> Edition Item 3
> "const Rational operator*(const Rational& lhs, const Rational& rhs);
> Many programmers squint when they first see this.

And rightly.

With the current language definition it prevents optimizations like Andrei's
Mojo move semantics.

C++0x is another matter.


> Why should the result of operator* be a const object?

Ideally it shouldn't, but there is no great harm, just a loss of possible
optimization.


> Because if it weren't, clents would be able to
> commit atrocities like this:
> Rational a, b, c;
> ...
> (a * b) = c; // invoke operator= on the result of a*b!
> ..."
>
> You might not see that example as typed but if( a * b = c) ... does occure
> because of typing mistakes. The compiler will catch this.

And why would you want to prevent that?


> Now this might not apply to the operator== but it is a practice I've picked
> up and just haven't changed.

It would be a good idea to change it (see above).


Cheers, & hth.,

- Alf

--
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?
From: 3DCoderGuy on
"Ben Voigt [C++ MVP]" <rbv(a)nospam.nospam> wrote in message
news:%23Y6NdXSsIHA.2292(a)TK2MSFTNGP03.phx.gbl...
>> Thanks Alexander for your reply.
>> The use of const on the return comes from Scott Meyers' Effective C++
>> Third Edition Item 3
>> "const Rational operator*(const Rational& lhs, const Rational& rhs);
>> Many programmers squint when they first see this. Why should the
>> result of operator* be a const object? Because if it weren't, clents
>> would be able to commit atrocities like this:
>> Rational a, b, c;
>> ...
>> (a * b) = c; // invoke operator= on the result of a*b!
>> ..."
>>
>> You might not see that example as typed but if( a * b = c) ... does
>> occure because of typing mistakes. The compiler will catch this.
>>
>> Now this might not apply to the operator== but it is a practice I've
>> picked up and just haven't changed.
>
> Good enough. It's not that const in the return type is wrong -- it
> certainly isn't, and Scott makes a very good argument for including it --
> it just isn't necessary for correct usage of the operator to work. On the
> other hand making the function const is necessary, otherwise the compiler
> will throw errors when you test for equality with a const reference.
>
>>
>> Thanks again
>> Mark
>
>

I love the fact that after 20 years of coding I'm still learning every day.



Thanks for that Ben.

Mark