Подтвердить что ты не робот

Когда создаются шаблоны функций constexpr?

Я работаю над предложением создать функциональные функции заголовка constexpr. (std::invoke, std::reference_wrapper, std::bind, std::mem_fn, std::not_fn)

Я узнал, что добавление constexpr может нарушить существующий код, потому что функции constexpr с нетерпением создаются.

template<class T>
int f(T){
    return T::not_existing_member;
}

template<class T>
constexpr int g(T){
    return T::not_existing_member;
}

int main(){
    decltype(f(0)) a; // Well-formed
    decltype(g(0)) b; // Ill-formed if the function body is instantiated
}

GCC компилирует этот код, clang - нет. Я описываю в мое предложение, как вы можете обрабатывать нетерпеливое создание с помощью перегрузок с помощью примера std::bind.

Можете ли вы сказать мне, где в стандарте это описано, когда компилятор должен и когда ему разрешено создавать экземпляр шаблона функции?

Точнее, я хочу знать, если в следующем примере идентичное поведение GCC и clang выполняется стандартом или определяется реализацией:

template<class T>
struct Foo{
    constexpr int f(){
        return 0;
    }

    constexpr int f()const{
        return T::not_existing_member;
    }
};

int main(){
    /* constexpr */ Foo<int> foo;
    foo.f(); // Ill-formed with, Well-formed without constexpr by the standard?
}

Оба GCC и clang компилируют код, если foo не constexpr, и оба отклоняют его, если он есть.

4b9b3361

Ответ 1

Пример # 1 активен CWG-выпуск 1581. В настоящее время не полностью определено, каково должно быть правильное поведение. Кажется, что направление constexpr должно быть желательным, но это необходимо уточнить в какой-то момент в будущем.

Пример # 2 прост: вызов int Foo<int>::f() const плохо сформирован. Это происходит, когда ваш объект foo равен const, но не тогда, когда он не const. Функции-члены шаблонов классов генерируются только при использовании, и если ваш объект Foo<int> не является const, мы никогда не создаем экземпляр функции-члена const, поэтому код корректно сформирован. constexpr здесь не имеет значения.