I'm working on a proposal to make the functional header functions constexpr
. (std::invoke
, std::reference_wrapper
, std::bind
, std::mem_fn
, std::not_fn
)
I've learned that adding constexpr
can break existing code because constexpr
functions are eagerly instantiated.
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 compiles this code, clang doesn't. I describe in my proposal how you can handle the eager instantiation with overloads using the example of std::bind
.
Can you tell me where in the standard it is described when a compiler has to and when it is allowed to instantiate a function template?
More precisely I want to know if in the following example the identical behavior of GCC and clang is enforced by the standard or is implementation defined:
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?
}
Both GCC and clang compile the code if foo
is not constexpr
and both reject it if it is.
Example #1 is active CWG issue 1581. It is currently not completely specified what the correct behavior should be. The direction seems to be that constexpr
instantiation should be eager, but this needs to be clarified at some point in the future.
Example #2 is straightforward: invoking int Foo<int>::f() const
is ill-formed. That happens when your foo
object is const
but not when it's non-const
. Member functions of class templates are only instantiated when used, and if your Foo<int>
object is non-const
, we never instantiate the const
member function, so the code is well-formed. constexpr
isn't relevant here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With