title: Force type definition with traits
body: <p>I wrote these classes that represent a graph:</p>
  
  <pre><code>class Node{
  
    public:
      typedef std::vector&lt;Node&gt;::iterator iterator;
      iterator begin() {return neigh.begin();}
      iterator end() {return neigh.end();}
  
    public:
      Node(std::string n) : name(n) {}
  
      std::string getName() {return name; }
  
      void addNeigh(Node n){
        neigh.push_back(n);
      } 
  
    private:
      std::string name;
      std::vector&lt;Node&gt; neigh;
  };
  
  class Map{
  
    public:
      typedef std::vector&lt;Node&gt;::iterator iterator;
      iterator begin() {return nodes.begin();}
      iterator end() {return nodes.end();}
  
    public:
      Map(std::string n) : map_name(n) {}
  
      void addNode(Node n){
        nodes.push_back(n);
      }
  
  
      std::string getName() { return map_name; }
      int getNumNodes() {return nodes.size();}
  
    private:
      std::string map_name;
      std::vector&lt;Node&gt; nodes;
  
  };
  </code></pre>
  
  <p>Then i want to write a function <code>printGraph</code> that prints some graph informations using a traits:</p>
  
  <pre><code>template&lt;typename T&gt;
  struct GraphTraits{
  
  };
  
  template&lt;&gt;
  struct GraphTraits&lt;Map&gt;{
  
    typedef Map::iterator node_iterator;
  
    static node_iterator node_begin(Map map){ return map.begin();}
    static node_iterator node_end(Map map) { return map.end();}
  
    static std::string getName(Map m) {return m.getName();}
  
  };
  
  template&lt;typename T&gt;
  void printGraph(T t){
    std::cout &lt;&lt; std::endl 
              &lt;&lt; "--------------------------------------" &lt;&lt; std::endl  
              &lt;&lt; "|             printGraph             |" &lt;&lt; std::endl  
              &lt;&lt; "--------------------------------------" &lt;&lt; std::endl;
    std::cout &lt;&lt; "Graph name: " &lt;&lt; GraphTraits&lt;T&gt;::getName(t) &lt;&lt; std::endl;
  
    for(GraphTraits&lt;T&gt;::node_iterator it = GraphTraits&lt;T&gt;::node_begin(t), e = GraphTraits&lt;T&gt;::node_end(t);
          it != e; ++it) {
            std::cout&lt;&lt; (*it).getName() &lt;&lt; std::endl; }
  }
  </code></pre>
  
  <p>If i try to compile this code i get these errors:</p>
  
  <pre><code>grafo.cpp:75:37: error: expected ';' in 'for' statement specifier
    for(GraphTraits&lt;T&gt;::node_iterator it = GraphTraits&lt;T&gt;::node_begin(t), e = GraphTraits&lt;T&gt;::node_end(t);
                                      ^
  grafo.cpp:75:37: error: use of undeclared identifier 'it'
  grafo.cpp:75:73: error: use of undeclared identifier 'e'
    for(GraphTraits&lt;T&gt;::node_iterator it = GraphTraits&lt;T&gt;::node_begin(t), e = GraphTraits&lt;T&gt;::node_end(t);
                                                                          ^
  grafo.cpp:76:9: error: use of undeclared identifier 'it'
          it != e; ++it) {
          ^
  grafo.cpp:76:15: error: use of undeclared identifier 'e'
          it != e; ++it) {
                ^
  grafo.cpp:76:16: error: expected ')'
          it != e; ++it) {
                 ^
  grafo.cpp:75:6: note: to match this '('
    for(GraphTraits&lt;T&gt;::node_iterator it = GraphTraits&lt;T&gt;::node_begin(t), e = GraphTraits&lt;T&gt;::node_end(t);
       ^
  grafo.cpp:76:20: error: use of undeclared identifier 'it'
          it != e; ++it) {
                     ^
  grafo.cpp:75:23: error: unexpected type name 'node_iterator': expected expression
    for(GraphTraits&lt;T&gt;::node_iterator it = GraphTraits&lt;T&gt;::node_begin(t), e = GraphTraits&lt;T&gt;::node_end(t);
                        ^
  grafo.cpp:104:3: note: in instantiation of function template specialization 'printGraph&lt;Map&gt;' requested here
    printGraph(mappa);
    ^
  </code></pre>
  
  <p>I can solve and compile successfully substituting:</p>
  
  <pre><code>for(GraphTraits&lt;T&gt;::node_iterator....
  </code></pre>
  
  <p>with:</p>
  
  <pre><code>for(GraphTraits&lt;Map&gt;::node_iterator....
  </code></pre>
  
  <p>But this makes <code>printGraph</code> to loose it's generality.</p>
  
  <p>Can someone give me some hint to solve the problem?</p>
  
  <p>Talking in generale, is it possible to use a Traits to force a data-type definition? I mean:</p>
  
  <pre><code>template&lt;typename T&gt;
  struct ATraits{
   -&gt; type "iterator" must be defined
  };
  </code></pre>
  
  <p>such that every specialization has to define:</p>
  
  <pre><code>typedef ..something.. iterator;
  </code></pre>