• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

nested template and dependent name

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am working on a template Graph data structure, which is an STL vector of GraphNode objects.  I defined the GraphNode class nested inside the Graph class and when I invoke the overload the insertion operator for the GraphNode object inside the overloaded insertion operator for the Graph object Visual Studio 15 (C++) reports,

(30): warning C4346: 'myGraph<T>::myGraphNode': dependent name is not a type
(30): note: prefix with 'typename' to indicate a type
(30): error C2061: syntax error: identifier 'myGraphNode'
(33): error C2805: binary 'operator <<' has too few parameters

Here is the function definition


I tried to fix this error by using the word typename in the formal parameter but that gives me the following errors
(49): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const myGraph<int>::myGraphNode' (or there is no acceptable conversion)

Here is that function code


I put the typename on the right side of the const and I get the same error.  Can anyone help.

Paul
 
Rancher
Posts: 280
VI Editor C++ Debian
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please provide the following details:

  • Definition of myGraph, including declaration of myGraphNode
  • Instantiation of the template class
  • The line that calls to output your intantiated object
  •  
    Tom Tutone
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Sorry to be so terse in my question.  Thank you for your response.  I have searched for an answer and am really stumped.

    line 55: myGraph<int> g;

    line 58: cout << g << endl;

    which calls line 47: ostream& operator<<(ostream& strm, const myGraph<T>& g) {

    which calls line 30: ostream& operator<<(ostream& strm, const myGraph<T>::myGraphNode& gn) {

    which causes the error in the earlier post:

    if I change the second formal parameter to include typename:
    ostream& operator<<(ostream& strm, cons typename myGraph<T>::myGraphNode& gn) {
    The compiler generates the following error:
    (49): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const myGraph<int>::myGraphNode' (or there is no acceptable conversion)

     
    Anand Hariharan
    Rancher
    Posts: 280
    VI Editor C++ Debian
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Your code has ALL the following characteristics:

  • Templates!
  • Nested classes
  • The inner class using the template parameter of the outer class
  • Implementing the member functions of the template classes outside the class definition


  • I am no language lawyer, but I think it is reasonable to assume that ANY of the above could make the head of a C++ language lawyer hurt!  

    I hope this helps:  https://msdn.microsoft.com/en-us/library/71dw8xzh.aspx

    sincerely,
    - Anand
     
    Tom Tutone
    Greenhorn
    Posts: 3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for your response but I do not understand your comments (criticism).  I mean no disrespect but I would like to understand your perspective.  This is C++ code not Java.  Why not use the language features?

    1) templates: Good for code reuse.  Why make different graph classes graohInt, graphString, ... when the compiler is perfectly capable of generating similar code.  Back to the dark days of the C programming language.  Templates support generic programming.  Think the Standard Template Library.

    2) Why not nested classes?  A graphNode is only part of a graph and has no business being made/accessed outside of the graph class.  I made all the members public to simplify the access to the elements in this example.  Real code would have private members and a public interface.

    3) The graphNode contains one piece of data about the graph, so the graphNode is the template type, not the graph.  A graph is simply a vector of graphNodes.  I want to represent different graphs with different node values.  For example, integer or string node values, my data type node values, ...

    4) Why not keep the interface to the class clean and easy to read/see its functionality.  Many of the functions get rather long, addEdge, Kruskals algorithm, ...  
    The insertion operator must be implemented outside the class otherwise I would need to change the ostream class to include my data types.  This is not possible unless I make a new derived type of the ostream class.  What I am trying to do in the insertion operator is to call the classes member functions to display themselves.  That is why the graph calls the insertion operator on the grapNode class.  The graphNode knows about itself.  I am trying to overload the global insertion operator so it acts like the primitive data types.  Why should I need to treat my data types differently?  For example, if val is an int I would write cout << val << endl;  Why should I have to do something special (different) for my data types, like g.output(cout);

    I am happy to learn something new, but what I am doing should be allowed by the language and yet it seems the compiler has an issue with it.  How would you implement a general graph class?

    Sincerely,
    Tom
     
    Have you no shame? Have you no decency? Have you no tiny ad?
    We need your help - Coderanch server fundraiser
    https://coderanch.com/wiki/782867/Coderanch-server-fundraiser
    reply
      Bookmark Topic Watch Topic
    • New Topic