Этот вопрос был вдохновлен другим вопросом .Пытаясь ответить на этот вопрос, я поняла, что у меня много вопросов.Итак ... Рассмотрим следующее:
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).
Я пробовал эти 2 синтаксиса (syntaces?) Того, что, как я думаю, должно быть, оба из них терпят неудачу на 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
с, как это:
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.
}
Это не компилируется.Обход, который я упомянул, решает проблему, но я уверен, что проблема заключается в моем первоначальном вопросе - отсутствует имя типа, но вы не знаете, где его придерживаться.Заранее большое спасибо.