I have a class inheriting from boost::noncopyable
; say, with header excerpt as follows:
class A : boost::noncopyable {
...
blah
...
private:
struct impl;
boost::scoped_ptr<impl> m_impl;
};
Then in one of the projects of my solution, I have a class (that also happens to inherit from boost::noncopyable
), one whose private members in an implementation detail is a reference to an object of type A, say, in the header excerpt:
class B : boost::noncopyable {
...
blah
...
private:
struct impl;
boost::scoped_ptr<impl> m_impl;
};
and in the implementation excerpt (cpp):
struct B::impl {
impl(A& a) : m_a(a) {}
set_A(A& a) {m_a = a;}
A& m_a;
...
}
B(A& a) : m_impl(new impl(a)) {}
...
Then in another project of my solution, I have a class C inheriting from B, say, with a header excerpt:
class C : public B {
...
blah;
...
private:
struct impl;
boost::scoped_ptr<impl> m_impl;
};
and in the implementation excerpt (cpp):
struct C::impl {
impl(A& a) : m_a(a) {}
void set_A(A& a) {m_a = a;}
A& m_a;
};
C(A &a) : B(a), m_impl(new impl(a)) {}
...
But when I try to build in MSVC++ 2008, I get the following error:
error C2248: 'boost::noncopyable_::noncopyable::operator =' : cannot access private member declared in class 'boost::noncopyable_::noncopyable'
see declaration of 'boost::noncopyable_::noncopyable::operator ='
error C2248: 'boost::scoped_ptr<T>::operator =' : cannot access private member declared in class 'boost::scoped_ptr<T>' with T = A::impl
This diagnostic occurred in the compiler generated function 'A& A::operator =(const A&)'
The compiler only has an issue with C's set_A
function, not B's set_A
. Appreciate if anyone has any ideas on this and can shed some light? Thanks as always for your interest.
To summarize, what I don't understand here is why the compiler is picky about when to apply the error regarding boost::noncopyable
. When I comment out the set_A(..)
function in class C, everything compiles OK. But when I keep it, it gives the error, whereas it doesn't have any problems with the same in class B. I also edited the error message above slightly to give more detail. I note here that it stated something about a compiler generated function. Could it be that this happened only with class C for some reason? Why?
[EDIT]
First of all, now I better understand your question, but I still do not understand why don't you want to change your implementation to:
struct C::impl {
impl(A& a) : m_a(&a) {}
void set_A(A& a) {m_a = &a;}
A* m_a;
};
With A
non-copyable this will simple do not work:
void set_A(A& a) {m_a = a;}
Anyway:
This error:
error C2248: 'boost::scoped_ptr::operator =' : cannot access private member declared in class 'boost::scoped_ptr' with T = A::impl
is because boost::scoped_ptr<T>
is non-copyable and this fact is not related to the fact that your A
class is not copyable.
This error:
This diagnostic occurred in the compiler generated function 'A& A::operator =(const A&)'
is for sure because of one of XXX::set_A(A& a) { m_A = a; }
functions. In such function A::operator =(const A&)
is required - and because it is not defined compiler try to define the default one. Default one will copy members one by one - and one of A
members is non-copyable boost::scoped_ptr<A::impl>
.
Then the most important for you question - why only one error - not for both XXX::set_A(A& a) { m_A = a; }
methods?
I tested simplified version of your case in my g++ 4.5.x enviroment. The diagnosis is very similar to yours - and the effect is very similar - only one set_A
function is complained - the first one. This is because A& operator = (const A&)
is needed for both - but generate only for the first one. g++ gives the excelent diagnosis:
../src/AnExample.cpp:24:32: note: synthesized method 'A& A::operator=(const A&)' first required here
My example and diagnosis:
class noncopyable {
private:
noncopyable(const noncopyable&);
noncopyable& operator = (const noncopyable&);
};
class A {
noncopyable m;
};
class B {
B(A& a) : a(a) {}
void set_A(A& a) { this->a = a; } // line 24
A& a;
};
class C {
C(A& a) : a(a) {}
void set_A(A& a) { this->a = a; }
A& a;
};
make all
Building file: ../src/AnExample.cpp
Invoking: Cygwin C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/AnExample.d" -MT"src/AnExample.d" -o "src/AnExample.o" "../src/AnExample.cpp"
../src/AnExample.cpp: In member function 'A& A::operator=(const A&)':
../src/AnExample.cpp:15:17: error: 'noncopyable& noncopyable::operator=(const noncopyable&)' is private
../src/AnExample.cpp:18:9: error: within this context
../src/AnExample.cpp: In member function 'void B::set_A(A&)':
../src/AnExample.cpp:24:32: note: synthesized method 'A& A::operator=(const A&)' first required here
make: *** [src/AnExample.o] Error 1
src/subdir.mk:18: recipe for target `src/AnExample.o' failed
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