CRTP и c ++ 1y возвращают тип удержания

Недавно я играл с CRTP, когда наткнулся на что-то, что меня удивило, когда я использовал функции c ++ 1y, тип которых выводится. Следующий код работает:

template
struct Base
{
    auto foo()
    {
        return static_cast(this)->foo_impl();
    }
};

struct Derived:
    public Base
{
    auto foo_impl()
        -> int
    {
        return 0;
    }
};

int main()
{
    Derived b;
    int i = b.foo();
    (void)i;
}

Я предположил, что тип возвращаемого значения изBase::foo былdecltype возвращенного выражения, но если я изменю функциюfoo как это:

auto foo()
    -> decltype(static_cast(this)->foo_impl())
{
    return static_cast(this)->foo_impl();
}

Этот код больше не работает, я получаю следующую ошибку (из GCC 4.8.1):

||In instantiation of 'struct Base':|
|required from here|
|error: invalid static_cast from type 'Base* const' to type 'Derived*'|
||In function 'int main()':|
|error: 'struct Derived' has no member named 'foo'|

Мои вопросы: почему нетэто работает? Что я мог бы написать, чтобы получить правильный тип возвращаемого значения, не полагаясь на автоматическое удержание возвращаемого типа?

И, ну ... вотживой пример.

Ответы на вопрос(2)

Ваш ответ на вопрос