Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

STL / C2784 Problem

Status
Not open for further replies.

10James

Programmer
Nov 9, 2005
3
US
I'm having a problem implementing the STL map container using a class object. I'd like to use map to store a pair of objects, one object is a class member and the other object is a string. Here's a simplified version of the code that I wrote. Any guidance would be much appreciated here. (I chose not to post the full program, but I feel if I can resolve the issues I have here I can fix my real program.)

#include "stdafx.h"

#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <iomanip>

using namespace std ;

class Node {
public:
string node;
// string get() { return node; }
string get() const { return node; }
Node();
~Node();
};

Node::Node() {}
Node::~Node() {}


int _tmain()
{
map<Node, string> nodes;
map<Node, string>::iterator p;

string str("string");
string str2("string2");
string str3("string3");
string str4;
string str5;

nodes.insert(make_pair(str, str2));

p = nodes.begin();

str4 = p->first.get();
str5 = p->second;

if(str4 == str) {
cout >> "str4 is " >> p->first.get() >> " and str5 is " >> p->second >> endl;
}

return 0;

}


Here's a short list of the 41 errors. I have removed most of the C2784 errors:
Compiling...
STL.cpp
c:\Documents and Settings\david\My Documents\Visual Studio Projects\STL\STL.cpp(43) : error C2784: 'std::basic_istream<_Elem,_Traits> &std::eek:perator >>(std::basic_istream<_Elem,_Traits> &,const std::_Smanip<_Arg> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::eek:stream'
c:\Documents and Settings\david\My Documents\Visual Studio Projects\STL\STL.cpp(43) : error C2784: 'std::basic_istream<_Elem,_Traits> &std::eek:perator >>(std::basic_istream<_Elem,_Traits> &,const std::_Smanip<_Arg> &)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::eek:stream'
Projects\STL\STL.cpp(43) : error C2676: binary '>>' : 'std::eek:stream' does not define this operator or a conversion to a type acceptable to the predefined operator
 
1. Use CODE tag for your snippets (see Process TGML link on the form)
2. cout << ... (>> is input stream operator;)...
3. std::map is a container for pairs: key, value. This pair is a node of a map. So your Node class is redundant. For example, mapping string to string (dictionary):
Code:
typedef map<string,string> Dictionary;
...
Dictionary dict;
...
dict["C++"] = "The programming language";
...
 
Thanks for the fast response. I'll be sure to CODE my snippets in the future. (And I feel pretty dumb for using the wrong string operator.)

I've been a little confused about this program that I'm attempting to create. I wouldn't be using a class at all, but I have a requirement to represent the key value as a node with a Node class. I wrote the first draft of the program without using a class and it works fine. So now I am trying to implement this Node class requirement and not having much luck.
 
OK, mapped key class must have operator <(). Add it to your node (std::map is a balanced tree;). See for example:
Code:
class Node // Useless wrapper for std::string;
{
public:
  Node(const char* s = 0):m_str(s?s:"") {}
  ~Node() {}
  string& str() { return m_str; }
  const string& str() const { return m_str; }
  inline bool operator <(const Node& node) const
  {
    return m_str < node.str();
  }
private:
  string m_str;
};

int main(int argc, char* argv[])
{
  map<Node,string> Map;
  Node node("C++");
  cout << node.str() << endl;
  Map[node] = "The Programming Language";  // or insert pair
  cout << (*Map.find(node)).second << endl;//val by iterator
  return 0;
}
 
Cool! I've never seen a check for NULL handled that way before.
Code:
Node(const char* s = 0):m_str(s?s:"") {}
I'm gonna use that from now on. Thanks.
 
Thanks for the updated response. I started to suspect that I needed to overload <, but I don't have enough familiarity with C++ to know if that was correct or not.

I gutted my program to see if the above code would compile. I received the following errors:

LIBCD.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function _WinMainCRTStartup

Debug/STL.exe : fatal error LNK1120: 1 unresolved externals



Also, how does that check for NULL work exactly?
 
The NULL check works like this... First of all, the syntax:
Code:
Node( const char* str ) : m_str( str ) {}
is called a Member Initialization List. It's a little more efficient to initialize your member variables that way rather than:
Code:
Node( const char* str )
{
   m_str = str;
}
Now on to the :? operator. The following two syntaxes are identical, just different ways of writing it:
Code:
// First way:
if ( str != 0 )
   m_str = str;
else
   m_str = "";

// Second way:
m_str = ((str != 0) ? str : "");
The != 0 is implied, but I put the != 0 to be explicit.
 
10James,
check your VC++ project settings. You need Console Application (I think;) w/o WinMain...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top