提问人:Magnar Myrtveit 提问时间:6/20/2023 最后编辑:JeJoMagnar Myrtveit 更新时间:6/21/2023 访问量:68
如何使类型别名对派生类不可见?
How to make type alias invisible to derived classes?
问:
我有一组基图类,用于处理派生的图类。我有一个模板类,它把派生的图类作为模板参数,然后把基图类(如和)作为模板参数。CRTP
GraphTypes
Edge
Node
GraphTypes
在基类中,我使用类型别名 () 来简化派生类的使用。我希望这些类型别名仅在基图类中可见,而在派生的图类中不可见。这可能吗?graph
using
有关设置,请参阅下面的代码,以及在派生类中使用基图类中的类型别名的问题。
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`.
};
}
答:
3赞
JeJo
6/20/2023
#1
始终可以限定完整命名空间
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(::MyGraph::EdgeType Type);
// ^^^^^^^^^^^^^^^^^^
// or
// Edge(MyGraph::EdgeType Type);
};
}
或者为类型/类型别名使用不同的名称以避免混淆。
话虽如此,如果您坚持保持名称不变,并且不想从基类中使用它们,请通过类/结构为这些别名类型提供间接。
namespace DirectedGraph
{
// ....
template<class GraphTypes>
class Edge {
private:
public:
struct Internal { // moved under the Internal struct!
using NodeType = typename GraphTypes::NodeType;
using EdgeType = typename GraphTypes::EdgeType;
};
auto This() -> typename Internal::EdgeType&;
};
}
namespace MyGraph {
// ....
enum class EdgeType { A, B, C };
class Edge : public DirectedGraph::Edge<GraphTypes> {
Edge(EdgeType Type); //Now you can!
};
}
1赞
Jan Schultke
6/20/2023
#2
我假设您不想重命名.如果您愿意这样做,您可以为不同的别名使用不同的名称,而不会遇到此问题。EdgeType
Edge
要在不更改任何名称的情况下解决此问题,您可以通过在以下位置声明另一个别名来进行影子:DirectedGraph::Edge<T>::EdgeType
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);
};
别名将遮蔽基类作用域和周围作用域中的任何声明,因此您可以像这样消除歧义。MyGraph::Edge::EdgeType
评论
GraphTypes