I have a set of base graph classes that use CRTP
to work with the derived graph classes. I have a template class GraphTypes
that take the derived graph classes as template parameters, and then the base graph classes, like Edge
and Node
, take GraphTypes
as template parameter.
Inside the base graph
classes, I use type aliases (using
) to simplify using the derived classes. I would like these type aliases to only be visible inside the base graph classes, and not in the derived graph classes. Is this possible?
See the code below for the setup, and an issue where the type alias in the base graph class is being used in the derived class.
namespace DirectedGraph
{
template<class NodeT, class EdgeT>
class GraphTypes
{
public:
using NodeType = NodeT;
using EdgeType = EdgeT;
};
template<class GraphTypes>
class Edge
{
private:
using NodeType = typename GraphTypes::NodeType;
using EdgeType = typename GraphTypes::EdgeType;
public:
auto This() -> EdgeType&;
};
}
namespace MyGraph
{
class Node;
class Edge;
using GraphTypes = DirectedGraph::GraphTypes<Node, Edge>;
enum class EdgeType { A, B, C };
class Edge : public DirectedGraph::Edge<GraphTypes>
{
Edge(EdgeType Type); // `EdgeType` is interpreted as the type alias `DirectedGraph::Edge::EdgeType` instead of the enum `MyGraph::EdgeType`.
};
}
I am assuming that you don't want to rename EdgeType
in Edge
. If you were willing to do that, you could just use different names for different aliases and not run into this issue.
To solve this issue without changing any names, you can shadow DirectedGraph::Edge<T>::EdgeType
by declaring another alias inside of MyGraph::Edge
:
class Edge : public DirectedGraph::Edge<GraphTypes> {
// possibly make this private
using EdgeType = MyGraph::EdgeType;
// we could also use MyGraph::EdgeType directly here, but that would be uglier
Edge(EdgeType Type);
};
The MyGraph::Edge::EdgeType
alias will shadow any declarations in the scope of the base class and in the surrounding scope, so you can disambiguate like this.