Visual C++ 5.0 Standard C++ Library
Frequently Asked Questions

C++ Library  
 
 

I am getting compiler error C2784 when instantiating STL containers with a user defined type parameter. How do I fix this problem?

I get the compiler error C2955 when using the "using" Declaration. How do I fix this problem?

When mixing the old iostream headers with the Standard C++ Library headers I get compiler error C2664 or C2782. What is causing this?

When I assign a shorter string to an existing string which contained a longer string originally the assignment corrupts the heap. How do I fix this problem?

How do I export STL components? Why do I get an access violation when accessing STL objects created in a DLL?

I am getting compiler error C2065: 'list' : undeclared identifier. What does this mean?

Is the Standard C++ Library thread safe?

I am getting compiler warnings C4786 and/or C4788. None of the symbols in my program is anywhere near 255 characters in length. What is causing this?

How do I look for Standard C++ Library, Standard Template Library (STL) related Knowledge Base Articles?

I am getting compiler error C2065: '<class-name>' undeclared identifier, and compiler error C2440 : 'conversion': cannot convert from 'type1' to 'type2'. What is causing this?


I am getting compiler error C2784 when instantiating STL containers with a user defined type parameter. How do I fix this problem?

This error is caused due to a bug in the Visual C++ 5.0 compiler. The bug has been fixed in the latest Visual Studio 97 Service Pack.

For details see the following articles in the Microsoft Knowledge Base:

ARTICLE-ID: Q166721
TITLE: FIX: C2784 on < Operator When Instantiating an STL Container
ARTICLE-ID: Q168078
TITLE FIX: C2784 Instantiating STL Objects With a UDT Parameter

MORE INFORMATION

While instantiating an STL container like vector or list, with a user defined data type, causes compiler error C2784. This error could be caused because of the following bugs in Visual C++ 5.0 compiler.

  1. The Visual C++ 5.0 compiler forces the instantiation of inline template member functions regardless of whether they are referenced. The member function generated is later discarded if it is not referenced. The following sample demonstrates.
    	//Compile options: /GX
    
    	#include <vector>
    
    	using namespace std ;
    
    	struct MyClass 
    	{
    	//members here
    	} ;
    
    	int main()
    	{
    		vector<MyClass> vMyClass ;
    		return 0 ;
    	}
    	
    The C2784 error message means the compiler is looking for operator< and operator== functions which take MyClass type as argument(s). operator< and operator== may be defined as class members or as global operators.
    In the sample above the compiler should not require the operator< and operator== to be declared or defined since they are not referenced anywhere in the code.

  2. The problem is caused by the nested namespace std::rel_ops. The Visual C++ 5.0 compiler is unable to do a proper name lookup for the generic relational operators '!=', '<=', '>', '>=', which are defined in the namespace std::rel_ops and are referenced by several STL components. The following sample demonstrates.
    	//Compile options: /GX
    
    	#include <list>
    
    	using namespace std ;
    
    	class X {
    	public:
    		X() {}
    		X(int i) { N = i ;}
    		bool operator==(const X& b) const { return N == b.N; }
    		bool operator<(const X& b) const { return N < b.N; }
    	private:
    		int N;
    	};
    
    	int main()
    	{
    		list <X> xList;
    		X x1(1), x2(2) ;
    	
    		xList.push_back(x1) ;
    		xList.push_back(x2) ;
    		xList.sort() ;
    		return 0;
    	}
    	
    The error C2784 is caused because the compiler is unable to do a proper name lookup for the generic relational operators '!=', '<=', '>', '>=', which are defined in the namespace std::rel_ops in terms of operator< and operator==. The relational operators are being referenced in the sort member function of the list class.

I get the compiler error C2955 when using the "using" Declaration. How do I fix this problem?

This error is caused due to a bug in the Visual C++ 5.0 compiler. The bug has been fixed in Visual Studio 97 Service Pack 1.

For details see the following articles in the Microsoft Knowledge Base:

ARTICLE-ID: Q168028
TITLE: FIX: C2955 Caused by the "using" Declaration

MORE INFORMATION

If you try to use the "using" declaration on a template class defined in a namespace the compiler generates error C2955. The following sample demonstrates.

	// Compiler Options: /GX 

	#include <list>

	using std::list ; //C2955 here

	int main()
	{
		list<int> li ;
		return 0 ;
	}

When mixing the old iostream headers with the Standard C++ Library headers I get compiler error C2664 or C2782. What is causing this?

Mixing the old iostream headers with the Standard C++ Library headers is not recommended.

Here are some examples, which have been known to cause problems when mixing the old iostream headers and the Standard C++ Library headers.

MORE INFORMATION

EXAMPLE 1: The following sample causes compiler error C2664, 'function' : cannot convert parameter number from 'type1' to 'type2'; different basic types

	//Compile options: /GX
	#pragma warning (disable : 4786)

	#include <iostream.h>
	#include <iostream>
	#include <vector>
	#include <iterator>
	#include <string>

	typedef std::vector <float> FloatArray;
	typedef std::ostream_iterator <float, char, 
				std::char_traits <char> > FloatOstreamIt;

	int main ()
	{
		// a vector of floats
		FloatArray rgFA;

		// an ostream iterator that outputs a float to cout 
		// terminated  by a space
		FloatOstreamIt OstreamIt(cout," "); //C2664 here
		//Workaround: Change the above line to 
		// FloatOstreamIt OstreamIt(std::cout," ");

		// Initialize the array to 1,1/2,1/3,...
		for (int i=0; i<10; i++) rgFA.push_back(1.0f/(i+1));

		// Print the array
		std::copy(rgFA.begin(),rgFA.end(),OstreamIt);
	
		cout << endl;

		return 0 ;
	}

EXAMPLE 2: The following sample causes compiler error C2872 'symbol' : ambiguous symbol

	//Compile options: /GX
	#pragma warning (disable : 4786)

	#include <iostream.h>
	#include <iostream>

	using namespace std ;

	int main()
	{
		cout << "Hello World" << endl ; //C2872 here
		return 0 ;
	}

To workaround this problem, remove the using namespace directive. If you remove the using directive the cout from the old iostream is used. To use cout from the Standard C++ Library use fully qualified names for example, std::cout.

EXAMPLE 3: The following sample demonstrates the result of mixing old iostream and Standard C++ Library components.

	//Compile options: /GX
	#pragma warning (disable : 4786)

	#include <iostream.h>
	#include <iostream>

	int main()
	{
		int n ;

		cout << "Enter a number from 1 - 10: " ;
		std::cin >> n ;
		cout << "The number you entered is: " << n << endl ;
		return 0 ;
	}

When you run the program you will see the output is not in the order one would expect.

When I assign a shorter string to an existing string which contained a longer string originally the assignment corrupts the heap. How do I fix this problem?

This problem is caused due to a bug in the Standard C++ Library basic_string class implementation. When assigning a shorter string to an existing string, which contained a longer string originally, the heap gets corrupted. The following sample demonstrates.

	//Compile options: /GX
	#include <crtdbg.h>
	#include <string>

	using namespace std;

	int main()
	{
		string  str, str2;
    	str = "abcdefghijklmnopqrstuvwxyzabcdefghij" ;
    	str2 = str;
		//Workaround, uncomment the following line
		//str.erase() ;
    	str = "zyxw" ;  
		_CrtCheckMemory() ;
    
		return(0);
	}

To workaround the problem call the string::erase member function before assigning the new value to the existing string.

How do I export STL components? Why do I get an access violation when accessing STL objects created in a DLL?

It is possible to export an instantiation of a Standard Template Library (STL) class. You can also export a class that contains a data member that is an STL object.

Note that you may not export a generalized template. The template must be instantiated, that is, all of the template parameters must be supplied and must be completely defined types at the point of instantiation. For instance "stack;" instantiates the STL stack class. The instantiation forces all members of class stack to be generated.

For details see the following article in the Microsoft Knowledge Base:

ARTICLE-ID: Q168958
TITLE: HOWTO: Exporting STL Components Inside and Outside a Class

When accessing a STL object created in one DLL or EXE through a pointer or reference in a different DLL or EXE, you may experience an access violation or other serious program errors including the appearance of data corruption or data loss. For details see the following article in the Microsoft Knowledge Base:

ARTICLE-ID: Q172369
TITLE PRB: Access Violation Caused when Accessing STL Object in DLL

I am getting compiler error C2065: 'list' : undeclared identifier. What does this mean?

The Standard C++ Library components are defined in the namespace 'std'. To use one of the Standard C++ Library components, you need to identify the components by using a fully qualified name, or using the using declaration or the using directive. The following sample demonstrates the problem and the workarounds.

	// Compiler Options: /GX 

	#include <list>

	//Workarounds: uncomment one of the following lines

	//using std::list ;		//1. using declaration
	//using namespace std ;	//2. using directive


	int main()
	{
		//Workaround: 3. use "std::list<int> li ;" instead of the following line
		list<int> li ;
		return 0 ;
	}

Is the Standard C++ Library thread safe?

Global objects instantiated from Standard Template Library classes are not thread safe. It may be possible for one thread to modify or change the state of the global object while another thread is using it, causing unpredictable results. One should confine the use of such an object to a single thread, or provide a scheme to serialize the threads' access to the object.

I am getting compiler warnings C4786 and/or C4788. None of the symbols in my program is anywhere near 255 characters in length. What is causing this?

C4786/C4788 is issued when a symbol's name exceeds 255 characters in length. This often happens with templates and especially STL components.

It is usually safe to ignore this warning. Use a #pragma warning (disable: 4786,4788) to suppress the messages.

See Visual C++ Books On Line "Build Errors - Compiler Warning (level 1) C4786" for further details.

How do I look for Standard C++ Library, Standard Template Library (STL) related Knowledge Base Articles?

You can query the Microsoft Knowledge Base using the keyword STLIss. This will get you a list of the entire Standard C++ Library related Knowledge Base articles.

The Microsoft Knowledge Base is available online at Microsoft Technical Support Knowledge Base.

The following Microsoft Knowledge Base article tells you how to search for Language Articles by KBSubcategory:

ARTICLE-ID: Q117552
TITLE: HOWTO: Search for Languages Articles by KBSubcategory

I am getting compiler error C2065: '<class-name>' undeclared identifier, and compiler error C2440 : 'conversion': cannot convert from 'type1' to 'type2'. What is causing this?

Defining a STL container (which stores user defined type objects), in a user defined namespace, generates compiler errors C2065 and C2440. The following sample demonstrates the problem.

#include <vector>

namespace MyCollections
{
	class C1 {} ;
	std::vector<C1> vC1 ;
}

This problem is caused due to a bug in the Visual C++ 5.0 compiler. The problem arises due to namespace scope lookup. The compiler needs to do a double lookup - once in the scope of namespace 'std' and once in namespace 'MyCollections', which the compiler doesn't do.

Do not use STL containers with user defined types inside a user-defined namespace.


© 1997 Microsoft Corporation. All rights reserved. Terms of Use.