CRTP и c ++ 1y возвращают тип удержания
Недавно я играл с CRTP, когда наткнулся на что-то, что меня удивило, когда я использовал функции c ++ 1y, тип которых выводится. Следующий код работает:
template<typename Derived>
struct Base
{
auto foo()
{
return static_cast<Derived*>(this)->foo_impl();
}
};
struct Derived:
public Base<Derived>
{
auto foo_impl()
-> int
{
return 0;
}
};
int main()
{
Derived b;
int i = b.foo();
(void)i;
}
Я предположил, что тип возвращаемого значения изBase<Derived>::foo
былdecltype
возвращенного выражения, но если я изменю функциюfoo
нравится:
auto foo()
-> decltype(static_cast<Derived*>(this)->foo_impl())
{
return static_cast<Derived*>(this)->foo_impl();
}
Этот код больше не работает, я получаю следующую ошибку (из GCC 4.8.1):
||In instantiation of 'struct Base<Derived>':|
|required from here|
|error: invalid static_cast from type 'Base<Derived>* const' to type 'Derived*'|
||In function 'int main()':|
|error: 'struct Derived' has no member named 'foo'|
Мои вопросы: почему это не работает? Что я мог бы написать, чтобы получить правильный тип возвращаемого значения, не полагаясь на автоматическое удержание возвращаемого типа?
И, ну ... вотживой пример.