iteong iteong - 2 months ago 16
C++ Question

Cannot recognise the typedef type defined in .h file

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*());
}




}

Answer
  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.

Comments