Thread: map::operator[]

  1. #1
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

    map::operator[]

    I'm getting 17 errors when I uncomment the line using map:: operator[]
    Code:
    	map<string, vector<double> > readSpeedsPerFile;
    	string filename( "blah" );
    	double speed = 0.0;
    ...
    //	readSpeedsPerFile[filename].push_back( speed );
    Did I do something wrong?

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    What are the errors?

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I get 0 errors when compiling the given code, even with the line. My Hat of Guessing doesn't even want to try to figure out what's in the "..." that may be causing the problem, especially when you don't even give us one of the seventeen errors.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cpjust View Post
    I'm getting 17 errors when...
    Come on cpjust, you've been here long enough to stop making the stupid newbie mistake of not posting the compile errors!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by iMalc View Post
    Come on cpjust, you've been here long enough to stop making the stupid newbie mistake of not posting the compile errors!
    OK, but you asked for it.
    Code:
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1372) : see declaration of 'std::operator <'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(142) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
            with
            [
                _Ty=std::string
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\map(72) : see reference to class template instantiation 'std::less<_Ty>' being compiled
            with
            [
                _Ty=std::string
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(26) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled
            with
            [
                _Kty=std::string,
                _Ty=std::vector<double>,
                _Pr=std::less<std::string>,
                _Alloc=std::allocator<std::pair<const std::string,std::vector<double>>>,
                _Mfl=false
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(68) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<std::string,std::vector<double>,std::less<std::string>,std::allocator<std::pair<const std::string,std::vector<double>>>,false>
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(94) : see reference to class template instantiation 'std::_Tree_ptr<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<std::string,std::vector<double>,std::less<std::string>,std::allocator<std::pair<const std::string,std::vector<double>>>,false>
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(112) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<std::string,std::vector<double>,std::less<std::string>,std::allocator<std::pair<const std::string,std::vector<double>>>,false>
            ]
            c:\Program Files\Microsoft Visual Studio 8\VC\include\map(82) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
            with
            [
                _Traits=std::_Tmap_traits<std::string,std::vector<double>,std::less<std::string>,std::allocator<std::pair<const std::string,std::vector<double>>>,false>
            ]
            ..\src\main.cpp(176) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
            with
            [
                _Kty=std::string,
                _Ty=std::vector<double>
            ]
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1372) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1372) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1372) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\vector(1276) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\vector(1276) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\vector(1276) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Alloc> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\vector(1276) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1880) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1880) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1880) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1880) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\utility(76) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\utility(76) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\utility(76) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::string'
            c:\Program Files\Microsoft Visual Studio 8\VC\include\utility(76) : see declaration of 'std::operator <'
    c:\Program Files\Microsoft Visual Studio 8\VC\include\functional(143) : error C2676: binary '<' : 'const std::string' does not define this operator or a conversion to a type acceptable to the predefined operator
    Here's everything including the "..."
    Code:
    #include <windows.h>
    #include <iostream>
    #include <iomanip>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <stdexcept>
    #include <climits>
    #include <ctime>
    #include <conio.h>
    
    using namespace std;
    
    
    vector<unsigned char>
    GetData( size_t  size )
    {
    	vector<unsigned char> data;
    
    	for ( size_t i = 0; i < size; ++i )
    	{
    		data.push_back( static_cast<unsigned char>( i % UCHAR_MAX ) );
    	}
    
    	random_shuffle( data.begin(), data.end() );
    	return data;
    }
    
    
    double
    TimedWrite( const char*  filename,
    				 size_t  megaBytes )
    {
    	// In case the file exists, delete it.
    	DeleteFile( filename );
    
    	DWORD dwFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH;
    
    	// Create a new file.
    	HANDLE file = CreateFile( filename,
    							  GENERIC_WRITE,		// dwDesiredAccess
    							  0,					// dwShareMode
    							  NULL,					// lpSecAttr
    							  CREATE_NEW,			// dwCreateDisp
    							  dwFlags,
    							  NULL );				// hTemplateFile
    
    	if ( file == INVALID_HANDLE_VALUE )
    	{
    		cerr << "Error opening file: " << filename << endl;
    		throw runtime_error( "Error opening file!" );
    	}
    
    	const size_t bufSize = 1024 * 1024;
    	vector<unsigned char> megabyte( GetData( bufSize ) );
    	unsigned long bytesWritten = 0;
    
    	// Start timing.
    	SYSTEMTIME start;
    	GetSystemTime( &start );
    
    	for ( size_t i = 0; i < megaBytes; ++i )
    	{
    		if ( WriteFile( file,
    						&megabyte[0],
    						bufSize,
    						&bytesWritten,
    						NULL ) == FALSE )
    		{
    			cerr << "Error writing to file!" << endl;
    			throw runtime_error( "Error writing to file!" );
    		}
    	}
    
    	SYSTEMTIME end;
    	GetSystemTime( &end );
    
    	if ( CloseHandle( file ) == FALSE )
    	{
    		cerr << "Error closing file!" << endl;
    		throw runtime_error( "Error closing file!" );
    	}
    
    	// Compare end - start times.
    	size_t msDiff = ((end.wMinute * 60 * 1000) - (start.wMinute * 60 * 1000)) +
    					((end.wSecond * 1000) - (start.wSecond * 1000)) +
    					(end.wMilliseconds - start.wMilliseconds);
    
    	double dMB		= megaBytes;
    	double dTime	= msDiff;
    	double MBperSec = dMB / (dTime / 1000.0);
    	return MBperSec;
    }
    
    
    double
    TimedRead( const char*  filename,
    				size_t  megaBytes )
    {
    	DWORD dwFlags = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH;
    
    	// Open an existing file.
    	HANDLE file = CreateFile( filename,
    							  GENERIC_READ,			// dwDesiredAccess
    							  0,					// dwShareMode
    							  NULL,					// lpSecAttr
    							  OPEN_EXISTING,		// dwCreateDisp
    							  dwFlags,
    							  NULL );				// hTemplateFile
    
    	if ( file == INVALID_HANDLE_VALUE )
    	{
    		cerr << "Error opening file: " << filename << endl;
    		throw runtime_error( "Error opening file!" );
    	}
    
    	const size_t bufSize = 1024 * 1024;
    	vector<unsigned char> megabyte( bufSize );
    	unsigned long bytesRead = 0;
    
    	// Start timing.
    	SYSTEMTIME start;
    	GetSystemTime( &start );
    
    	for ( size_t i = 0; i < megaBytes; ++i )
    	{
    		if ( (ReadFile( file,
    						&megabyte[0],
    						bufSize,
    						&bytesRead,
    						NULL ) == FALSE) || (bytesRead != bufSize) )
    		{
    			cerr << "Error reading from file!" << endl;
    			throw runtime_error( "Error reading from file!" );
    		}
    	}
    
    	SYSTEMTIME end;
    	GetSystemTime( &end );
    
    	if ( CloseHandle( file ) == FALSE )
    	{
    		cerr << "Error closing file!" << endl;
    		throw runtime_error( "Error closing file!" );
    	}
    
    	// Compare end - start times.
    	size_t msDiff = ((end.wMinute * 60 * 1000) - (start.wMinute * 60 * 1000)) +
    					((end.wSecond * 1000) - (start.wSecond * 1000)) +
    					(end.wMilliseconds - start.wMilliseconds);
    
    	double dMB		= megaBytes;
    	double dTime	= msDiff;
    	double MBperSec = dMB / (dTime / 1000.0);
    	return MBperSec;
    }
    
    
    void
    TimedReadWrite( vector<pair<string, size_t> >&  filenames,
    									   double&  avgRead,
    									   double&  avgWrite,
    									   double&  minRead,
    									   double&  maxRead,
    									   double&  minWrite,
    									   double&  maxWrite )
    {
    	typedef vector<pair<string, size_t> >::iterator	fileIter;
    	double speed = 0.0;
    	map<string, vector<double> > readSpeedsPerFile;
    	map<string, vector<double> > writeSpeedsPerFile;
    	avgRead  = 0;
    	avgWrite = 0;
    
    	for ( int i = 0; i < 10; ++i )
    	{
    		for ( fileIter it = filenames.begin(); it != filenames.end(); ++it )
    		{
    			string filename( it->first );
    			size_t fileSize = it->second;
    
    			speed = TimedWrite( filename.c_str(), fileSize );
    			avgWrite += speed;
    //			writeSpeedsPerFile[filename].push_back( speed );
    
    			speed = TimedRead( filename.c_str(), fileSize );
    			avgRead += speed;
    //			readSpeedsPerFile[filename].push_back( speed );
    
    			DeleteFile( filename.c_str() );
    		}
    	}
    
    	vector<double> minReadPerFile;
    	vector<double> maxReadPerFile;
    	vector<double> minWritePerFile;
    	vector<double> maxWritePerFile;
    	typedef map<string, vector<double> >::iterator	iter;
    
    	for ( iter it = readSpeedsPerFile.begin(); it != readSpeedsPerFile.end(); ++it )
    	{
    		minReadPerFile.push_back( *min_element( it->second.begin(), it->second.end() ) );
    		maxReadPerFile.push_back( *max_element( it->second.begin(), it->second.end() ) );
    	}
    
    	for ( iter it = writeSpeedsPerFile.begin(); it != writeSpeedsPerFile.end(); ++it )
    	{
    		minWritePerFile.push_back( *min_element( it->second.begin(), it->second.end() ) );
    		maxWritePerFile.push_back( *max_element( it->second.begin(), it->second.end() ) );
    	}
    
    	minRead = *min_element( minReadPerFile.begin(), minReadPerFile.end() );
    	maxRead = *max_element( maxReadPerFile.begin(), maxReadPerFile.end() );
    	minWrite = *min_element( minWritePerFile.begin(), minWritePerFile.end() );
    	maxWrite = *max_element( maxWritePerFile.begin(), maxWritePerFile.end() );
    
    	avgWrite /= 10;
    	avgRead /= 10;
    }
    
    
    int main()
    {
    	typedef pair<string, size_t>	FileAndSize;
    	vector<FileAndSize> filenames;
    	filenames.push_back( FileAndSize( "1MB.fil",	1 ) );
    	filenames.push_back( FileAndSize( "10MB.fil",	10 ) );
    	filenames.push_back( FileAndSize( "50MB.fil",	50 ) );
    	filenames.push_back( FileAndSize( "100MB.fil",	100 ) );
    
    	double avgRead	= 0.0;
    	double avgWrite	= 0.0;
    	double minRead	= 0.0;
    	double maxRead	= 0.0;
    	double minWrite	= 0.0;
    	double maxWrite	= 0.0;
    
    	TimedReadWrite( filenames,
    					avgRead,
    					avgWrite,
    					minRead,
    					maxRead,
    					minWrite,
    					maxWrite );
    
    	cout << "Read speed:" << endl
    		 << "   Average:" << avgRead << "MB/s." << endl
    		 << "   Minimum:" << minRead << "MB/s." << endl
    		 << "   Maximum:" << maxRead << "MB/s." << endl
    		 << "Write speed:" << endl
    		 << "   Average:" << avgWrite << "MB/s." << endl
    		 << "   Minimum:" << minWrite << "MB/s." << endl
    		 << "   Maximum:" << maxWrite << "MB/s." << endl;
    
    	cout << endl << "Press any key to continue." << endl;
    	_getch();
    	return 0;
    }
    I didn't think the rest would be relevent to the errors since it compiles just fine with those lines commented out, but as soon as I uncomment one of them, I get that huge mess of STL error hell.
    So I assumed I must have been doing something wrong by using map:: operator[] in that way.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    It compiles fine on my windows gcc . One thing: the bottom says that it can't find operator< for std::string, and I don't see #include<string> anywhere. Maybe?

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by tabstop View Post
    It compiles fine on my windows gcc . One thing: the bottom says that it can't find operator< for std::string, and I don't see #include<string> anywhere. Maybe?
    Son of a...!
    I knew it had to be something stupid like that.
    Why it compiles some strings without the <string> header and only complains when you use the string in some other way, I have no idea. Shouldn't the compiler just say "string? What the hell is a string?"

    Thanks.

  8. #8
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by cpjust View Post
    Shouldn't the compiler just say "string? What the hell is a string?"
    I thought C compiler errors were cryptic at first. Then eventually I saw C++ compilers errors. I now love C errors.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cpjust View Post
    Son of a...!
    I knew it had to be something stupid like that.
    Why it compiles some strings without the <string> header and only complains when you use the string in some other way, I have no idea. Shouldn't the compiler just say "string? What the hell is a string?"

    Thanks.
    I have a feeling that iomanip or iostream define enough of it to be able to do their jobs, but not all of it. OTOH, who can tell?

    And yes, the fact that there are 25 messages that all say "can't find operator <" in slightly different ways really illustrates the power of templates.

Popular pages Recent additions subscribe to a feed