Why does the following code (stripped down to the bare minimum) not
build?
To be specific, it gives me a linker error like this:
error LNK2019: unresolved external symbol "class Matrix<double,3,3>
__cdecl operator-(class Matrix<double,3,3> const &)"
(??G@YA?AV?$Matrix@N$02$02@@ABV0@@Z) referenced in function _main
The problem seems to be the need to access private members in the
overloaded operator definition and the subsequent friend declaration in
the class. Forward declaring the function outside the class does not
change anything.
Compiler is VC++ 8.0 EE.
To my surprise, it did and does work using VC++ 7.0.
What is the issue and how can I resolve it? Slightly puzzled over this
seemingly simple problem...
Thanks,
Michael
-----------------
#include <iostream>
#include <algorithm>
#include <vector>
template<typename T, unsigned int d, unsigned int e> class Matrix
{
private:
friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m );
typedef std::vector<T> data_type;
data_type data_;
public:
Matrix( T value )
{
data_.resize( d * e );
std::fill( data_.begin(), data_.end(), value );
}
// ...
};
template <typename T, unsigned int d, unsigned int e>
Matrix<T, d, e> operator-( const Matrix<T, d, e>& m )
{
Matrix<T, d, e> mRes( m );
Matrix<T, d, e>::data_type::iterator itrEnd = mRes.data_.end();
for ( Matrix<T, d, e>::data_type::iterator itr =
mRes.data_.begin(); itr != itrEnd; ++itr )
(*itr) = -(*itr);
return mRes;
}
template <typename T, unsigned int d, unsigned int e, unsigned int f>
Matrix<T, d, f> operator*( const Matrix<T, d, e>& m1,
const Matrix<T, e, f>& m2 )
{
// does multiplication without accessing
// private members of Matrix<>
// ...
return Matrix<T, d, f>( 0.0 ); // dummy return
}
int main()
{
Matrix<double, 3, 3> m( 1.0 );
Matrix<double, 3, 3> n( 2.0 );
Matrix<double, 3, 3> o = m * n; // no problems
Matrix<double, 3, 3> p = -n; // yields linker error
return ( EXIT_SUCCESS );
}
-----------------
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Michael
|
5/1/2006 3:33:38 PM |
|
Problem is, that U don't specify body of
friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m ).
Try this code:
template<typename T, unsigned int d, unsigned int e> class Matrix
{
private:
friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m ) {
Matrix<T, d, e> m(1.0);
return m;
}
typedef std::vector<T> data_type;
data_type data_;
public:
Matrix( T value )
{
data_.resize( d * e );
std::fill( data_.begin(), data_.end(), value );
}
// ...
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
malvoj
|
5/2/2006 10:36:01 AM
|
|
Michael Hofmann <mhofmann79@arcor.de> writes:
> #include <iostream>
> #include <algorithm>
> #include <vector>
>
> template<typename T, unsigned int d, unsigned int e> class Matrix
> {
> private:
> friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m );
This declares a non-template.
>
> typedef std::vector<T> data_type;
> data_type data_;
>
> public:
> Matrix( T value )
> {
> data_.resize( d * e );
> std::fill( data_.begin(), data_.end(), value );
> }
>
> // ...
> };
template<typename T, unsigned int d, unsigned int e> class Matrix;
template<typename T, unsigned int d, unsigned int e>
Matrix<T, d, e> operator-( const Matrix<T, d, e>& m );
template<typename T, unsigned int d, unsigned int e> class Matrix
{
friend Matrix<T, d, e> operator- <>( const Matrix<T, d, e>& m );
etc.
should help.
> template <typename T, unsigned int d, unsigned int e>
> Matrix<T, d, e> operator-( const Matrix<T, d, e>& m )
This defines a template.
> {
> Matrix<T, d, e> mRes( m );
> Matrix<T, d, e>::data_type::iterator itrEnd = mRes.data_.end();
> for ( Matrix<T, d, e>::data_type::iterator itr =
> mRes.data_.begin(); itr != itrEnd; ++itr )
> (*itr) = -(*itr);
> return mRes;
> }
>
> template <typename T, unsigned int d, unsigned int e, unsigned int f>
> Matrix<T, d, f> operator*( const Matrix<T, d, e>& m1,
> const Matrix<T, e, f>& m2 )
> {
> // does multiplication without accessing
> // private members of Matrix<>
> // ...
> return Matrix<T, d, f>( 0.0 ); // dummy return
> }
>
> int main()
> {
> Matrix<double, 3, 3> m( 1.0 );
> Matrix<double, 3, 3> n( 2.0 );
> Matrix<double, 3, 3> o = m * n; // no problems
Non non-template to be referenced here, so the template specialization
is referenced.
> Matrix<double, 3, 3> p = -n; // yields linker error
This references the non-template, which hasn't yet be defined.
> return ( EXIT_SUCCESS );
> }
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Thomas
|
5/2/2006 10:37:05 AM
|
|
Michael Hofmann wrote:
> Forward declaring the function outside the class does not
> change anything.
The trouble is that the friend declaration declares a non-template
function, which overload resolution dutifully selects as the best
match. But, of course, the non-template operator-() isn't defined
anywhere, hence the link error.
To fix this, you'll need to forward declare the template operator-()
(before the definition of class Matrix) and amend the friend
declaration:
friend Matrix<T, d, e> operator- <> ( const Matrix<T, d, e>& m );
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
johnchx2
|
5/2/2006 10:43:12 AM
|
|
|
3 Replies
274 Views
(page loaded in 0.063 seconds)
Similiar Articles: Non-member operator overloading, linker complains - comp.lang.c++ ...Problem is, that U don't specify body of friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m ). Try this code: template<typename T, unsigned int d, unsigned ... Overloading operators new and delete - comp.lang.c++.moderated ...Non-member operator overloading, linker complains - comp.lang.c++ ... Non-member operator overloading, linker complains - comp.lang.c++ ... Problem is, that U ... pragmas ... const member functions in classes derived from templates. - comp ...Non-member operator overloading, linker complains - comp.lang.c++ ... const member functions in classes derived from templates. - comp ... You simply attempted to call a ... class definition containing member of own type - comp.lang.c++ ...Non-member operator overloading, linker complains - comp.lang.c++ ..... to be the need to access private members in the overloaded operator definition ... vector<T> data ... Use of MATLAB fftshift - comp.dsp... So, if I want previous replies to be seen by members ... your own array class, say, RBJarray, and overload the operator? ... you have forced people to adopt non-standard non ... Non-member operator overloading, linker complains - comp.lang.c++ ...Problem is, that U don't specify body of friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m ). Try this code: template<typename T, unsigned int d, unsigned ... Overloading operators new and delete - comp.lang.c++.moderated ...Non-member operator overloading, linker complains - comp.lang.c++ ... Non-member operator overloading, linker complains - comp.lang.c++ ... Problem is, that U ... pragmas ... 7/26/2012 3:45:21 PM
|