class A
{
static int iterator;
class iterator
{
[...]
};
[...]
};
Run Code Online (Sandbox Code Playgroud)
我(我想)理解为什么typename需要这里:
template <class T>
void foo() {
typename T::iterator* iter;
[...]
}
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么typename不需要这里:
void foo() {
A::iterator* iter;
[...]
}
Run Code Online (Sandbox Code Playgroud)
谁能解释一下?
编译器之所以没有后者的问题,我发现在评论中得到了很好的回答:
在A::iterator我的情况下,我不明白为什么编译器不会混淆它static int iterator? - xcrypt
@xcrypt因为它知道两者A::iterator是什么,并且可以根据它的使用方式选择哪一个 - Seth Carnegie
typename我认为编译器在合格的从属名称之前需要的原因在Kerrek SB接受的答案中得到了很好的回答.请务必阅读有关该答案的评论,尤其是iammilind的评论:
"T :: A*x ;,对于T :: A是一个类型且T :: A是一个值的情况,这个表达式都可以为真.如果A是一个类型,那么它将导致指针声明;如果A是一个值,然后它将导致乘法.因此,单个模板对于2种不同类型将具有不同的含义,这是不可接受的."
我发现了一些类似的问题(例如 这个),但没有一个真正回答我的问题.请考虑以下代码段:
template<unsigned int rows, unsigned int cols,typename arrtype>
class Variance
{
double f(const arrtype &);
};
template<unsigned int rows, unsigned int cols>
double Variance<rows,cols,Eigen::Matrix<double,rows,cols>>
::f(const Eigen::Array<double,rows,cols> & M)
{
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
正如您在专业化中所看到的,类型arrtype将取决于rows和cols.上面的代码导致编译器错误(g ++ 5.4.0):
invalid use of incomplete type ‘class Variance<rows, cols, Eigen::Matrix<double, rows, cols> >
Run Code Online (Sandbox Code Playgroud)
我已经尝试typename arrtype<rows, cols>过模板声明,但后来抱怨这arrtype 不是一种类型,这是有道理的.
使用依赖于其他模板类型的模板化类型的正确方法是什么?