0

I'm creating an adjacency list to modelize an oriented weighted graph, and i'd like to know if recursive alias templates are possibe. I've tried something like this

template<class edge_data>
using graph_test = std::set<std::map<std::set<graph_test>::const_pointer, edge_data>>;

(each entry of the set is a map, and each map represents a vertex. each entry of the maps are edges: keys are pointers to other vertices, values are weight. the pointers are not invalidated on insertion)

This produces an error : 'graph_test': undeclared identifier.

I know I could use std::any to avoid this problem, but it look a bit 'dangerous', even if I know what I'm doing.

Do you have any suggestions/ideas that might solve this problem ?

EDIT 1: As Igor Tandetnik pointed it out, the way I create my const_pointer could not be correct. I came up with this code (modifications in italic):

template<class edge_data>
    using graph_test = std::set<std::map<graph_test<edge_data>::const_pointer, edge_data>>;

The problem and the error are still here, but it's a least one mistake fixed.

EDIT 2: I took a look at bipll's solution, which was very relevant, and Dani's comment, showing a probable lack of typedef keyword. I came up with this piece of code, and it compiles:

template<class edge_data> struct graph_test
    : std::set<typename std::map<typename graph_test<edge_data>::const_pointer, edge_data>> {
    using std::map<typename graph_test<edge_data>::const_pointer, edge_data>::map;
};

I will mark with question as solved, thank you very much for your time and help :)

Antoine
  • 25
  • 1
  • 6
  • `std::set` expects `T` to be a type, but `graph_test` is not a type - it's a class template, an infinite family of types. For that reason alone, `std::set` already doesn't make sense. – Igor Tandetnik Jul 01 '18 at 13:35
  • Possible duplicate of [How to define a recursive type?](https://stackoverflow.com/questions/25563661/how-to-define-a-recursive-type) – cpplearner Jul 01 '18 at 13:57
  • Well it's the same kind of problem, but I'm using an alias template instead of a typedef, so it wouldn't have helped a lot. But you're a bit of right, it kind of looks similar. – Antoine Jul 01 '18 at 14:15

1 Answers1

0

In your definition, graph_test lacks a template parameter, and a typename is missing. Besides, a type cannot be an alias to itself, its expansion would create an infinite dependency graph. You can make it a real type, not an alias:

template<class edge_data> struct graph_test
    :std::set<
        typename std::map<typename std::set<graph_test<edge_data>>::const_pointer, edge_data>>
{
    using std::map<typename std::set<graph_test<edge_data>>::const_pointer, edge_data>>::map;
};
bipll
  • 11,747
  • 1
  • 18
  • 32
  • Thanks, your answer looks great :) However I got many errors when I tried it, do you think it could come from the compilers arguments ? – Antoine Jul 01 '18 at 14:02
  • I think you're missing typename before `std::set>::const_pointer` – Daniel Jul 01 '18 at 14:03