Когда создаются шаблоны функций 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
, и оба отклоняют его, если он есть.
Ответы
Ответ 1
Пример # 1 активен CWG-выпуск 1581. В настоящее время не полностью определено, каково должно быть правильное поведение. Кажется, что направление constexpr
должно быть желательным, но это необходимо уточнить в какой-то момент в будущем.
Пример # 2 прост: вызов int Foo<int>::f() const
плохо сформирован. Это происходит, когда ваш объект foo
равен const
, но не тогда, когда он не const
. Функции-члены шаблонов классов генерируются только при использовании, и если ваш объект Foo<int>
не является const
, мы никогда не создаем экземпляр функции-члена const
, поэтому код корректно сформирован. constexpr
здесь не имеет значения.