Внутренняя ошибка компилятора VS2015 при вызове метода constexpr базового класса

Следующий код выдает внутреннюю ошибку компилятора (VS2015)

struct A
{
    constexpr A(){}
    constexpr int bar()
    {
        return 3;
    }
};

struct B : A
{
    constexpr B(){}
    constexpr int foo()
    {
        return A::bar();
    }
};

int main()
{
    constexpr B b;
    constexpr int dummy = b.foo();
    return 1;
}

Однако, если бы я удалил квалификатор A:::

constexpr int foo()
{
    return bar();
}

это будет скомпилировано. Проблема возникает, когда эти методы имеют одинаковые имена, и мне нужно вызвать метод базового класса. (например, при использовании рекурсивного наследования шаблонов)

какие-нибудь обходные пути?

2 ответа

Актуальная проблема b объявлен как const (constexpr подразумевает const на объектах), и вы пытаетесь позвонить неconst (начиная с C++14, constexpr не подразумевает const о методах, см. здесь) метод с const объект...

Согласно стандарту, вы не сможете решить проблему, просто удалив A:: ни по static_cast как ты. Предварительно RTM-версия Visual Studio 2015 позволяет вам делать это только потому, что ее поддержка constexpr является предварительным и очень глючным. C++ 11 constexpr (но, к сожалению, не C++ 14 расширенный constexpr) ожидается полная поддержка в RTM-версии VS 2015 (см. здесь).

Правильная версия вашего кода:

struct A
{
    constexpr A(){}
    constexpr int bar() const
    {
        return 3;
    }
};

struct B : A
{
    constexpr B(){}
    constexpr int foo() const
    {
        return A::bar();
    }
};

int main()
{
    constexpr B b;
    constexpr int dummy = b.foo();
    return 1;
}

Нашел решение. "this" должно быть приведено к const A*:

struct B : A
{
    constexpr B(){}
    constexpr int foo()
    {
        return static_cast<const A*>(this)->bar();
    }
};

Также работает, когда методы имеют одинаковые имена.

Другие вопросы по тегам