晕哦,这问题我弄一下午了,好像有点眉目了,但是……
为了分析模板定义,编译器必须能够区分出是类型以及不是类型的表达式。对于编译器来说,它并不总是能够区分出模板定义中的哪些表达式是类型。比如如果编译器在模板定义中遇到表达式R::name ,且R 这个模板类型参数代表了一个类,那么name引用的是R的一个类型成员吗?编译器无法知道name是否为一个类型,因为它只有在模板被实例化之后才能找到R表示的是类的定义。
告诉编译器一个表达式是类型表达式的机制是在表达式前加上关键字typename 。
这句话我没看明白,到底是什么意思呢?最好举个例子,谢谢。
哪位大哥受累帮忙把cunsh(村少) 给我的解释写全了啊,写成一个完整的程序,好叫我看得明白点。
cunsh(村少) 给我的解释如下:
class T{
//...
public:
typedef int INT;
};
template<class T>
class test
{
public:
T::INT *kk; //如果你想让 kk 为整形指针.你可能这么写.
};
现在改一下class T .
class T {
public:
static int INT;
};
那在test类中你写的 T::INT *kk; 就可能是一个乘法语句.
最后没办法.你只好拿出了typename这个关键字 告诉编译器 T::INT是个类型.
问题点数:20、回复次数:5Top
1 楼ugg(逸学堂(exuetang.net))回复于 2006-03-04 21:59:28 得分 0
typename T::INT *kk;
~~~~~~~~~~~
如上,这样修改就可以告诉编译器,T::INT是一个类型,而不是一个变量。
就是这样。Top
2 楼tommy851027(努力,努力!)回复于 2006-03-04 22:27:26 得分 0
来个完整的好吗,我不清楚该如何组织成一个完整的程序Top
3 楼tommy851027(努力,努力!)回复于 2006-03-05 13:19:31 得分 0
晕,没人啦Top
4 楼adintr(www.adintr.com)(风流总被雨打风吹去)回复于 2006-03-05 14:40:39 得分 0
要编译通过 T::INT *kk; 编译器必须看到 T 的定义,
既然它都看到 T 的定义了, INT 是不是类型还推断不出来么Top
5 楼adintr(www.adintr.com)(风流总被雨打风吹去)回复于 2006-03-05 14:47:35 得分 20
“name”: 依赖名称不是类型
如果依赖名称将被视为一个类型,则 typename 关键字是必需的。这是在 Visual C++ .NET 2003 编译器中进行的重大更改,以便符合 ISO C++ 标准。
有关更多信息,请参见编译时的重大更改摘要。
为使代码在 Visual C++ 的所有版本中以同样方式工作,请将 typename 添加到声明中。
下面的示例生成 C4346:
// C4346.cpp
// compile with: /WX /LD
template<class T>
struct C {
T::X* x; // C4346
// try the following line instead
// typename T::X* x;
};
以下示例显示 typename 关键字是必需的其他示例:
// C4346b.cpp
// compile with: /LD /W1
template<class T>
const typename T::X& f(typename T::Z* p); // Required in both places
template<class T, int N>
struct L{};
template<class T>
struct M : public L<typename T::Type, T::Value>
{ // required on type argument, not on non-type argument
typedef typename T::X Type;
Type f(); // OK: "Type" is a type-specifer
typename T::X g(); // typename required
operator typename T::Z(); // typename required
};
并且,
// C4346c.cpp
// compile with: /LD /WX
struct Y {
typedef int Y_t;
};
template<class T>
struct A {
typedef Y A_t;
};
template<class T>
struct B {
typedef /*typename*/ A<T>::A_t B_t; // C4346 typename needed here
typedef /*typename*/ B_t::Y_t B_t2; // typename also needed here
};
Top




