3

I'm having issues getting the compiler to recognise the return type for a function template in a .tem file (used for separating the implementation from the .h file).

In file included from tests/Graph.h:57:0,
                 from tests/test1.cpp:3:
tests/Graph.tem:28:2: error: ‘reference’ does not name a type
  reference Node_Iterator<N, E>::operator*() const {
  ^~~~~~~~~
tests/Graph.tem:33:2: error: ‘pointer’ does not name a type
  pointer Node_Iterator<N, E>::operator->() const {

Not sure what I did wrong. I used typedef to define the type for the return types.

/* 
 * File: Graph.h
 */

#ifndef _Graph_h
#define _Graph_h

#include <vector>
#include <algorithm>
#include <string>
#include <memory>
#include <iostream>
#include <exception>
#include <map>
#include <set>
#include <typeinfo>

namespace gdwg {

    template <typename N, typename E> class Graph; // function prototype for Graph class

//-----------------------------------------------------------
// Iterators for Graph with Nodes N and Edges E
//-----------------------------------------------------------

    // Iterator class for Node N
    template <typename N, typename E> class Node_Iterator {

    public:
            typedef typename Graph<N, E>::Node Node;

            typedef std::ptrdiff_t                     difference_type;
            typedef std::forward_iterator_tag          iterator_category;
            const typedef N                            value_type;
            const typedef N*                           pointer;
            const typedef N&                           reference;

            // operators for value and reference types
            reference operator*() const;
            pointer operator->() const;



    private:
            bool end;
            typename std::vector< std::shared_ptr<Node> >::iterator it;
            typename std::vector< std::shared_ptr<Node> > mynodes_;

    };


    #include "Graph.tem" // definition/implementation of Graph, Node_Iterator and Edge_Iterator classes

}

#endif

This is the .tem file which is the implementation of the Graph.h file, which I included at the bottom of the .h file.

#include <vector>
#include <algorithm>
#include <string>
#include <memory>
#include <iostream>
#include <exception>
#include <map>
#include <set>
#include <typeinfo>

namespace gdwg {

    //-----------------------------------------------------------
    // Implementation of Iterator class for Node N
    //-----------------------------------------------------------

    // operators for value and reference types
    template <typename N, typename E> 
    reference Node_Iterator<N, E>::operator*() const {
        return (*it)->val_;
    }

    template <typename N, typename E> 
    pointer Node_Iterator<N, E>::operator->() const {
        return &(operator*());
    }




}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
iteong
  • 715
  • 3
  • 10
  • 26

1 Answers1

1
  1. Add the qualified name for them (with typename keyword, see Where and why do I have to put the “template” and “typename” keywords?), like:

    typename Node_Iterator<N, E>::reference ...
    typename Node_Iterator<N, E>::pointer...

  2. In Graph.h, #include "Graph.tem" is inside the definition of the namespace gdwg, and in Graph.tem, the function is defined inside another namespace gdwg, then they'll be defined in namespace gdwg::gdwg. You could move #include "Graph.tem" out of the namespace definition in Graph.h, or remove the namespace definition in Graph.tem.

Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • It is supposed to be inside according to my specs though. Ok that error is gone but I got this: tests/Graph.tem:28:75: error: definition of ‘const N& gdwg::Node_Iterator::operator*() const’ is not in namespace enclosing ‘gdwg::Node_Iterator’ [-fpermissive] typename Node_Iterator::reference Node_Iterator::operator*() const { – iteong Sep 12 '16 at 07:12
  • @iteong That's the problem. `#include "Graph.tem"` in inside the definition of namespace `gdwg`, and inside `Graph.tem` another namespace `gdwg` is defined, at last become sth like `namespace gdwg { namespace gdwg { ...`. If you have to `#include "Graph.tem"` inside the definition of namespace, then remove the namespace definition in `Graph.tem`. – songyuanyao Sep 12 '16 at 07:19
  • Oh ok so do I remove the gdwg in the .tem file? – iteong Sep 12 '16 at 07:20
  • @iteong Yes, it should be fine. – songyuanyao Sep 12 '16 at 07:21