Wrapper::f() const
的定义没有使我的程序无效而感到困惑1,尽管它调用了一个非常量成员变量的非常量成员函数。// well-formed program (???)
// build with: g++ -std=c++17 -Wall -Wextra -Werror -pedantic
template<class T> struct Data { void f() {} };
template<class T> struct Wrapper
{
Data<T> _data;
void f() const { _data.f(); } // _data.f(): non-const!
};
int main()
{
Wrapper<void> w; // no error in instantiation point?
(void) w;
}
演示2
另一方面,如果Data
是一个非模板类3,我的编译器会发出诊断:
// ill-formed program (as expected)
// build with: g++ -std=c++17 -Wall -Wextra -Werror -pedantic
struct Data { void f() {} };
template<class T> struct Wrapper
{
Data _data;
void f() const { _data.f(); } //error: no matching function for call to 'Data::f() const'
};
int main()
{
Wrapper<void> w;
(void) w;
}
我觉得答案会包含表达式“推断上下文”之类的内容...但我真的无法确定规范中具体指定这种行为的部分。
有没有专业人士能为我解开这个谜团?
注:
1) 但是,如果我尝试有效地调用Wrapper<T>::f() const
,就会出现错误。
2) 我已经使用了-std=c++17
进行编译,但这不是特定于C++17的,因此没有特定的标签。
3) 在这个答案中,@Baum mit Augen引用了[N4140, 14.7.1(2)]
:
当特化被引用在需要存在成员定义的上下文中时,成员的特化被隐式实例化
但是,在编译片段(#2)中,尽管其“特化从未在需要成员定义存在的上下文中引用”,但void f() const { _data.f(); }
仍失败。
constexpr if
的内容... - YSC