Hi . What is the problem of this :

template < typename B >
ostream &operator << ( ostream &out, const Array < B > &a )

The compiler say "Link error" and ...

Dani AI

Generated

Quick diagnosis: the linker errors (unresolved Array<int>/Array<double> symbols and operator<<) mean the compiler never emitted the template instantiations. The header declares the template but the method bodies live in a separate translation unit, so the translation unit that builds main does not see the definitions and the linker cannot find the generated code.

Two straightforward fixes (pick one):

  • Put all template definitions where the compiler can see them when instantiating — typically the header. A common pattern is to keep declarations in Array.h and put implementations in an Array.tpp (or .inl) then include it at the end of the header:
/* at end of Array.h */
#include "Array.tpp"   // contains the template method definitions
  • Or keep the implementations in Array.cpp but explicitly instantiate the exact types you use (after the definitions in that .cpp). For example:
/* at bottom of Array.cpp */
template class Array<int>;
template class Array<double>;

(If operator<</>> are function templates in the .cpp as well, either move those definitions into the header or explicitly instantiate them too.)

Additional practical checks and gotchas:

  • Remove the stray semicolons after the template<typename B> lines in the implementation file — they’re incorrect and confusing.
  • Confirm Array.cpp is actually added to the Visual Studio project if using explicit instantiation.
  • The friend operator declaration in a class template can be subtle; the safest route is to define operator<</>> in the header (or use a public print method and have a thin header-visible operator<< call it).
  • ’s inline example showed ptr = a.ptr; and a different member name; avoid shallow copies (double-delete) and watch for typos like color vs size.
  • Avoid using namespace std; in headers and ensure ptr is initialized (delete[] ptr requires a valid or null pointer).

After moving the template bodies into a header or explicitly instantiating the used types, rebuilding will remove the LNK2019 errors.

Recommended Answers

All 6 Replies

>The compiler say "Link error" and ...
And what?
Could you please post the whole error message (plus code), and what's Array ?

My Program :

#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
using namespace std;

template < typename B >
class Array
{
	friend ostream &operator << ( ostream &, const Array < B > & );
	friend istream &operator >> ( istream &, Array < B > & );
public:
	Array ( int = 10 );
	Array ( const Array & );
	~Array ( );
	int getSize ( ) const;

	const B &operator = ( const Array & );
	bool operator == ( const Array & ) const;

	bool operator != ( const Array &right ) const
	{
		return ! ( *this == right );
	}

	B &operator [ ] ( int );
	B operator [ ] ( int ) const;
private:
	int size;
	B *ptr;
};

#endif
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include "Array.h"

using namespace std;

template < typename B >
Array < B >::Array ( int arraySize )
{
	size = ( arraySize > 0 ? arraySize : 10 );
	ptr = new B [ size ];

	for ( int i = 0; i < size; i++ )
		ptr [ i ] = 0;
}

template < typename B >
Array < B >::Array ( const Array &arrayToCopy ) : size ( arrayToCopy.size )
{
	ptr = new B [ size ];

	for ( int i = 0; i < size; i++ )
		ptr [ i ] = arrayToCopy.ptr [ i ];
}

template < typename B >
Array < B >::~Array ( )
{
	delete [ ] ptr;
}

template < typename B >
int Array < B >::getSize ( ) const
{
	return size;
}

template < typename B >
const B &Array < B >::operator = ( const Array &right )
{
	if ( &right != this )
	{
		if ( size != right.size )
		{
			delete [ ] ptr;
			size = right.size;
			ptr = new B [ size ];
		}

		for ( int i = 0; i < size; i++ )
			ptr [ i ] = right.ptr [ i ];
	}

	return *this;
}

template < typename B >
bool Array < B >::operator == ( const Array &right ) const
{
	if ( size != right.size )
		return false;

	for ( int i = 0; i < size; i++ )
		if ( ptr [ i ] != right.ptr [ i ] )
			return false;

	return true;
}

template < typename B >
B &Array < B >::operator [ ] ( int subscript )
{
	if ( subscript < 0 || subscript >= size )
	{
		cerr << "\nError: Subscript " << subscript << " out of range" << endl;
		exit ( 1 );
	}

	return ptr [ subscript ];
}

template < typename B >
B Array < B >::operator [ ] ( int subscript ) const
{
	if ( subscript < 0 || subscript >= size )
	{
		cerr << "\nError: Subscript " << subscript << " out of range" << endl;
		exit ( 1 );
	}

	return ptr [ subscript ];
}

template < typename B >
istream &operator >> ( istream &input, Array < B > &a )
{
	for ( int i = 0; i < a.size; i++ )
		input >> a.ptr [ i ];

	return input;
}

template < typename B >
ostream &operator << ( ostream &output, const Array < B > &a )
{
	int i;

	for ( i = 0; i < a.size; i++ )
	{
		output << setw ( 12 ) << a.ptr [ i ];

		if ( ( i + 1 ) % 4 == 0 )
			output << endl;
	}

	if ( i % 4 != 0 )
		output << endl;

	return output;
}
#include <iostream>
#include "Array.h"

using namespace std;

int main ( )
{
	Array < int > as ( 5 );
	cout << "Size of array is : " << as.getSize ( ) << "\nArray contents : " << as;

	Array < double > ad ( 6 );
	cout << "\nSize of array is : " << ad.getSize ( ) << "\nArray contents : " << ad;

	system ( "pause" );

	return 0;
}

And Error :

Error 1 error LNK2019: unresolved external symbol "public: __thiscall Array<int>::~Array<int>(void)" (??1?$Array@H@@QAE@XZ) referenced in function _main main.obj
Error 2 error LNK2019: unresolved external symbol "public: __thiscall Array<double>::~Array<double>(void)" (??1?$Array@N@@QAE@XZ) referenced in function _main main.obj
Error 3 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<double> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Array@N@@@Z) referenced in function _main main.obj
Error 4 error LNK2019: unresolved external symbol "public: int __thiscall Array<double>::getSize(void)const " (?getSize@?$Array@N@@QBEHXZ) referenced in function _main main.obj
Error 5 error LNK2019: unresolved external symbol "public: __thiscall Array<double>::Array<double>(int)" (??0?$Array@N@@QAE@H@Z) referenced in function _main main.obj
Error 6 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Array@H@@@Z) referenced in function _main main.obj
Error 7 error LNK2019: unresolved external symbol "public: int __thiscall Array<int>::getSize(void)const " (?getSize@?$Array@H@@QBEHXZ) referenced in function _main main.obj
Error 8 error LNK2019: unresolved external symbol "public: __thiscall Array<int>::Array<int>(int)" (??0?$Array@H@@QAE@H@Z) referenced in function _main main.obj
Error 9 fatal error LNK1120: 8 unresolved externals C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\Array\Debug\Array.exe

Could you please post using code tags?
Is it that difficult? Just click the # button (and past your code in between the tags).
Read also this and this :)

You failed to write the Array class's constructor implementation code.

#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
using namespace std;

template < typename B >
class Array
{
	friend ostream &operator << ( ostream &, const Array < B > & );
	friend istream &operator >> ( istream &, Array < B > & );
public:
	Array ( int x = 10 )

       {
             color = x;
             ptr = 0;
       }
	Array ( const Array & a )

       {
             color = a.color;
             ptr = a.ptr;
       }

	~Array ( );
	int getSize ( ) const;

	const B &operator = ( const Array & );
	bool operator == ( const Array & ) const;

	bool operator != ( const Array &right ) const
	{
		return ! ( *this == right );
	}

	B &operator [ ] ( int );
	B operator [ ] ( int ) const;
private:
	int size;
	B *ptr;
};

#endif

Excuse me . Could you please explain a bit more ?

Look in your textbook for class constructors. What I posted is called inline code. Or you can find more info online.

That header file has similar problems with all the other methods of that class. You have to write code that implements all those methods, or get the code from who ever you got that header file.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.