如何避免typedef?

时间:2010-12-12 15:04:21

标签: c++ templates typedef

template <class VertexType>
class GraphMatrix
{
};

template <class GraphType>
class Graph
{
 typedef typename GraphType::VertexType VertexType;
 GraphType* graph_;
 void addVertex(VertexType vertex)
 {
 }
 //...
};
int main()
{
    Graph <GraphMatrix <int> > graph;
    return 0;
}

看看我是否会将typedef VertexType VertexType;//A行添加到GraphMatrix class此代码将通过编译并将起作用,否则会出现编译错误。错误:C2039:'VertexType':不是'GraphMatrix'的成员。我的问题是:有没有一种方法(语法)使上面的代码工作而不添加这个愚蠢的行//A'?

4 个答案:

答案 0 :(得分:1)

您总是可以写出VertexType的完全限定名称,typedef只是一个快捷方式,它将该名称带入范围并让您编写更清晰的代码。

所以,在这种情况下,没有,没有别的办法。

使用继承时,您可以using BaseClass::something将其带入范围

答案 1 :(得分:1)

  

我的问题是:有没有一种方法(语法)使上面的代码工作而不添加这个愚蠢的行// A

我不这么认为。

但是您的代码存在一些问题。 GraphType是一个依赖名称,表示GraphType::VertexType是您需要在其中添加typename的类型。

但是,当为GraphType = GraphMatrix <int>实例化类模板时,编译器找不到GraphMatrix <int>::VertexType,因此您会收到另一个错误。

因此,为了修复错误,请将GraphMatrix的定义更改为

template <class TVertexType>
class GraphMatrix
{
    public:
    typedef TVertexType VertexType;    
};

或类似的东西。

完整的工作代码here

答案 2 :(得分:0)

如果要获取由template-parameter传递的模板化类的参数,则必须限制GraphType的允许类型。你通过专业化来做到这一点:

template <class GraphType>
class Graph;

template <template <class> class GraphType, class VertexType>
class Graph<GraphType<VertexType> >
{
  ... // use GraphType<VertexType> as your graph, VertexType as your vertex type
};

你甚至可以create a helper struct that will unpack the args for you

template <class T> struct get_arg;

template <template <class> class Tpl, class Arg>
struct get_arg<Tpl<Arg> >
{
  typedef Arg type;
};

但是请注意,此解决方案非常不灵活 - 它只允许带有一个参数的模板作为Graph类模板的参数(想象一下,如果向GraphMatrix添加参数,您会做什么模板)。因此通常不会使用它。

普通的解决方案是将typedef添加到你的类中(就像你使用&#34;愚蠢的行&#34;),或者甚至更好,使用traits类并专门化它们。

答案 3 :(得分:-1)

我对此表示怀疑。

Graph模板的角度来看,GraphType模板参数只是一个类型名称(因此在本例中为“一个类”)。因此,如果使用Graph实例化GraphType = GraphMatrix<int>,则Graph甚至无法检查是否已收到模板实例或“常规”类。因此,它无法访问其模板参数 - 因为GraphType甚至不需要任何模板参数。

将typedef引入GraphType会丰富模板GraphMatrix的每个实例,并提供有关它实例化的确切类型的公共信息 - 这正是您想要实现的目标。