作者:duoduo848511 | 来源:互联网 | 2022-10-16 10:21
给出以下示例:
// test.cpp
class A {
public:
private:
A& operator=(const A&); // don't allow assignment operator
A(const A&); // don't allow default copy constructor
void func();
};
template
class B {
public:
B(A &a) : a_(a) {}
void setA(A* a) { a_ = *a; } // No error is raised here.
void func();
protected:
B& operator=(const B&) { return *this; }
A& a_;
};
我希望void setA(A* a) { a_ = *a; }
B中会出现错误,因为A的赋值运算符被设为私有,而A和B不是朋友,但是在编译时不会出现错误。
$ g++ -c test.cpp // My invocation for reference
我的问题是为什么允许这样做?是否可以根据c ++标准保证这种行为?
我注意到,如果没有将B用作模板化类,则会得到预期的错误。
$ g++ -c test.cpp
test.cpp: In member function ‘void B::setA(A*)’:
test.cpp:11:29: error: ‘A& A::operator=(const A&)’ is private within this context
void setA(A* a) { a_ = *a; }
^
test.cpp:4:8: note: declared private here
A& operator=(const A&); // don't allow assignment operator
^~~~~~~~
这使我相信,因为实际上我不是在“使用”模板化的B,所以编译器可以简单地“忽略它”并对其进行优化。我发现这很难相信,因为我没有进行优化编译,而且当我使用模板化B时仍然无法重现该错误。
// Appending this to test.cpp still doesn't result in an error.
void func(A &alloc) {
B b(alloc);
b.func();
}
我还可以确认,对于常规方法,我会遇到预期的错误。将void func();
B 更改为void func() { a_.func(); }
:
test.cpp:14:22: error: 'func' is a private member of 'A'
void func() { a_.func(); }
^
test.cpp:6:10: note: declared private here
void func();
^
我已经证实铛++(V6.0.1),G ++(V7.4.0),和树铛的尖端这一切的行为,并反对-std=c++98
对-std=c++17
。
1> Igor Tandetn..:
setA
除非并且直到实际使用,否则类实例的非虚拟成员函数(例如您的示例)不会被实例化。