什么时候实例化 constexpr 函数模板?
When are constexpr function templates instantiated?
我正在研究一项提案,使功能 header 功能 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 不编译。我在 my proposal 中描述了如何使用 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?
}
如果 foo
不是 constexpr
,GCC 和 clang 都会编译代码,如果是,则都拒绝它。
示例 #1 有效 CWG issue 1581。目前还没有完全指定正确的行为 应该 是什么。方向似乎是 constexpr
实例化应该是急切的,但这需要在未来的某个时候明确。
示例 #2 很简单:调用 int Foo<int>::f() const
格式错误。当您的 foo
对象是 const
时会发生这种情况,但当它不是 const
时则不会。 class模板的成员函数只在使用的时候实例化,如果你的Foo<int>
对象是非const
的,我们从不实例化const
成员函数,所以代码很好-形成。 constexpr
与此处无关。
我正在研究一项提案,使功能 header 功能 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 不编译。我在 my proposal 中描述了如何使用 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?
}
如果 foo
不是 constexpr
,GCC 和 clang 都会编译代码,如果是,则都拒绝它。
示例 #1 有效 CWG issue 1581。目前还没有完全指定正确的行为 应该 是什么。方向似乎是 constexpr
实例化应该是急切的,但这需要在未来的某个时候明确。
示例 #2 很简单:调用 int Foo<int>::f() const
格式错误。当您的 foo
对象是 const
时会发生这种情况,但当它不是 const
时则不会。 class模板的成员函数只在使用的时候实例化,如果你的Foo<int>
对象是非const
的,我们从不实例化const
成员函数,所以代码很好-形成。 constexpr
与此处无关。