Как вы указали, тип, если он существует, известен компилятору, иначе он не будет существовать. Однако, это не всегда легко или даже доступно программисту на C ++ 03.
N1607 упомянуть в своем заключении следующее:
В C ++ 2003 невозможно до
выразить тип возврата функции
шаблон во всех случаях . Более того,
выражения, включающие призывы к
шаблоны функций обычно имеют очень
сложные типы, которые
практически невозможно написать
рука
Вопрос в том, как нам получить доступ к этому типу как к программисту. Это не всегда тривиальный процесс, часто неосуществимый. Это становится все более сложным, когда у вас есть выражение, для которого вы хотите знать тип результата. Вам придется разбить его на части, чтобы вычислить типы результатов. Невозможно упростить этот процесс с помощью шаблонов (во всяком случае, без оценки выражения). Нарушение выражения будет подвержено ошибкам, утомительным и кошмарным сном. Подумайте об этом коде:
x.g()[b.a(e)]->f();
В C ++ 98 / TR1 часто невозможно назвать типы, которые зависят от параметров шаблона. Traits предлагает нам так много информации, но в конечном итоге decltype является гораздо более чистым решением многих проблем. Большая часть информации доступна вам, когда метапрограммирование доступно только потому, что библиотеки, такие как boost или loki, используют несколько уловок, скрытых в темных углах языка C ++ 98.
Конечно, это не имеет отношения к вашему вопросу, но я считаю, что стоит упомянуть, что компиляторы C ++ 98 уже имеют механику, чтобы знать эти типы. Это именно то, что предлагает sizeof, за исключением того, что он возвращает вам размер. decltype повторно использует некоторые из этих функций и решает эти проблемы с большей элегантностью.
Что касается другого (академического) примера:
struct Foo
{
struct
{
int x;
} bar;
};
template<typename T>
void
f(const T& t)
{
// C++03, How can I name the type of T::bar ?
// C++0x
// decltype(t.bar) cpy;
// Do stuff with our local cpy
}
int
main()
{
f(Foo());
}