为什么模板typedef在C++(而不是C++11)中成为问题?

5
这个问题中,提问者询问了关于模板typedef的解决方案,但是在C++中并不可行。提问者自己提出了一个解决方案,但并不满意。
template<size_t N, size_t M>
class Matrix {
    // ....
};

// Problem - will not compile
typedef Matrix<N,1> Vector<N>;

// Solution
template <int N>
class Vector: public Matrix<N,1>
{ };

我的问题是,相较于 OP 的解决方案(假设这些类永远不会被用作基类指针或使用 new),Helper::type solution 给我们带来了什么优势?在发布版本中,空类应该不会带来额外的开销(或者确实会吗?)。我唯一能看到的缺点是,在调试构建时,你需要展开基类以进行调试。 编辑: 除了所选答案之外,还请参阅 @Dani 的答案,他建议继承版本需要定义构造函数,这是一个额外的不便。

如果没有其他问题,Helper::type 实际上就是正确的类型。我已经有一段时间没有认真研究这些东西了,但是如果我没记错的话,类型推导等方面可能存在一些微妙的问题。 - user1084944
3个回答

7

这是因为构造函数不会被继承(在C++11中,默认情况下也不会)。因此,您必须复制所有非默认构造函数,即使只是在实现中调用基类构造函数。


啊哈!由于某种原因,我忘记了这个!太好了,谢谢。 - Samaursa

7
typedef 的作用是定义类型别名。子类不是类型别名——它是一个新类型。
举个例子,想象一下某个库函数。
template<size_t N, size_t M>
Matrix<N, M> * createMatrix();

现在有了辅助类型。
Vector<3>::type * var = createMatrix<3, 1>();

是合法的。
通过继承

Vector<3> * var = createMatrix<3, 1>();

不是。


当然可以,但是我们每次都会创建新的类型(因为模板参数不同),所以最终真的有区别吗? - Samaursa

3
除了语法(可能是主观的),每个人的口味不同,主要区别在于,通过继承,向量实际上是另一种类型,可以退化成矩阵,而使用一个typedef包含的帮助器,向量是矩阵的别名(至少对于部分特化适用)。
这种差异要求向量重新定义构造函数(它们没有被继承),或者在基于模板特化的操作的情况下可能会出现一些潜在的问题(使用typedef时,它们永远不会被视为“不同”)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接