разница constexpr между g cc v10 и v9: ошибка или функция - PullRequest
6 голосов
/ 20 февраля 2020

Если скомпилировано с g cc v10, приведенный ниже код содержит ошибку, но для g cc v9 код в порядке.

template<auto N>
struct A {
    constexpr auto size() const {
        return N;
    }  
};

template<typename T>
void foo1(const T& a) {
    constexpr auto s = a.size(); // Why error here?
}
template<typename T>
void foo2(T a) {
    constexpr auto s = a.size(); // OK
}
int main() {
    A<10> x1;
    foo1(x1);
    foo2(x1);
    A<x1.size()> x2; // OK
    constexpr auto s = x1.size(); // OK
}

В моем понимании размер функции-члена () можно назвать constexpr в любом случае. Но есть один случай, когда поведение gcc10 изменилось по сравнению с gcc9: если аргумент передается const-ref. Я не понимаю, почему это не должно быть constexpr?

Другой пример:

template<auto N>
struct A {
    constexpr auto size() const {
        return N;
    }  
};

template<typename T>
constexpr void foo1(const T& a) {
    constexpr auto s = a.size(); // Why error here?
    return s;
}
template<typename T>
constexpr auto foo2(const T& a) {
    return a.size(); // Why OK here
}
int main() {
    A<10> x1;
    constexpr auto s1 = foo1(x1);
    constexpr auto s2 = foo2(x1);
}

Я не понимаю разницу.

1 Ответ

4 голосов
/ 20 февраля 2020

Это G CC ошибка 66477 . В нем упоминается, что G CC ошибочно принимает параметры ссылочного типа в константных выражениях.

Эта ошибка исправлена ​​для G CC 10.


Причина, по которой a.size() не допускается в константных выражениях, упоминается в этом посте .

...