Этот вопрос был вызван другим вопросом . Пытаясь ответить на этот вопрос, я понял, что у меня самого много вопросов. Итак ... Примите во внимание следующее:
struct S1
{
enum { value = 42 };
};
template struct S2
{
typedef S1 Type;
};
template struct S3
{
typedef S2 Type;
};
template struct S4
{
typedef typename T::Type::Type Type; //(1)//legal?
enum {value = T::Type::Type::value }; //(2)//legal?
};
int main()
{
S4 > > >::value;
}
Это успешно компилируется с MSVC9.0 и Online Comeau. Однако меня беспокоит то, что я не понимаю, к чему относится typename
в (1) и почему нам не нужно typename
в (2).
] Я пробовал эти 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
, например это:
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
struct ArraySize
{
typedef Bad Type;
};
template
struct ArraySize
{
typedef Good Type;
};
template
struct Boom
{
char arr[ArraySize::Type::value]; //error, negative subscript, even without any instantiation
};
int main()
{
Boom b; //with or without this line, compilation fails.
}
Это не компилируется. Обходной путь, о котором я упоминал, решает проблему, но я уверен, что проблема здесь в моем первоначальном вопросе - отсутствует имя типа, но вы действительно не знаете, куда его вставить. Заранее большое спасибо.