这个问题的灵感来自另一个问题。在试图回答这个问题时,我明白我自己有很多问题。所以......考虑以下几点:
struct S1
{
enum { value = 42 };
};
template <class T> struct S2
{
typedef S1 Type;
};
template <class T> struct S3
{
typedef S2<T> Type;
};
template <class T> struct S4
{
typedef typename T::Type::Type Type; //(1)//legal?
enum {value = T::Type::Type::value }; //(2)//legal?
};
int main()
{
S4<S3<S2<S2<S1> > > >::value;
}
这可以使用 MSVC9.0 和 Online Comeau 成功编译。但是,困扰我的是我不明白typename
(1)中指的是什么以及为什么我们不需要typename
(2)中的内容。
我已经尝试了这两种我认为应该在 MSVC 上失败的语法(语法?):
typedef typename T::typename Type::Type Type;
enum {value = typename T::typename Type::Type::value };
和
typedef typename (typename T::Type)::Type Type;
enum {value = (typename (typename T::Type)::Type)::value };
当然,一种解决方法是typedef
像这样使用连续的 s:
typedef typename T::Type T1;
typedef typename T1::Type Type;
enum { value = Type::value};
抛开好的风格,我们在语法上是否必须使用我提到的解决方法?
其余的只是一个有趣的例子。无需阅读。与问题无关。
请注意,虽然 MSVC 接受原始的奇怪语法而没有多个typename
s(我的意思是 (1) 和 (2)),但它会导致上述问题中的奇怪行为。我想我也会在这里以简洁的形式展示这个例子:
struct Good
{
enum {value = 1};
};
struct Bad
{
enum {value = -1};
};
template <class T1, class T2>
struct ArraySize
{
typedef Bad Type;
};
template <class T>
struct ArraySize<T, T>
{
typedef Good Type;
};
template <class T>
struct Boom
{
char arr[ArraySize<T, Good>::Type::value]; //error, negative subscript, even without any instantiation
};
int main()
{
Boom<Good> b; //with or without this line, compilation fails.
}
这不编译。我提到的解决方法解决了这个问题,但我确信这里的问题是我最初的问题 - 缺少类型名,但你真的不知道在哪里贴一个。首先十分感谢。