我正在制定一个使功能标头功能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都会编译代码,如果是document.Save(@"D:\workspace\folder1\Solution.Application.DataExporter\Export\mydocument.pdf");
则拒绝它。
答案 0 :(得分:6)
示例#1处于活动状态CWG issue 1581。目前尚未完全指定应该的正确行为。方向似乎是constexpr
实例化应该是急切的,但这需要在将来的某个时候澄清。
示例#2很简单:调用int Foo<int>::f() const
格式不正确。当您的foo
对象为const
而非非const
时,则会发生这种情况。类模板的成员函数仅在使用时被实例化,如果您的Foo<int>
对象不是const
,我们永远不会实例化const
成员函数,因此代码格式正确。 constexpr
与此无关。