Столкнулся с этим нюансом при написании сложного noncopyable класса, привел к простому примеру(в конце)
Проблема вот в чем, мой класс должен быть noncopyable и никогда фактически не копироваться, НО при той реализации что снизу, получается такая ругатня:
rilium@rilium:~/spectra_lib$ g++ test.cpp -I headers/ headers/noncopyable.hpp: In copy constructor ‘A::A(const A&)’: headers/noncopyable.hpp:24: error: ‘spectra::noncopyable::noncopyable(const spectra::noncopyable&)’ is private test.cpp:7: error: within this context test.cpp: In function ‘A f()’: test.cpp:17: note: synthesized method ‘A::A(const A&)’ first required here
Однако если убрать наследование от spectra::noncopyable(полный аналог boost:noncopyable) и раскоментировать конструктор копирования, его вызов фактически не происходит, причем не только касательно этого тестового класса, но и для любого другого, если новый локальный объект инициализируется возвращаемым из функции(проверял с помощью g++ -S)
Соответственно вопрос, это баг или фича? Как мне корректно добиться желаемого поведения - чтобы отказ в компиляции происходил ТОЛЬКО когда конструктор копирования действительно должен быть вызван. И из интереса, в каких случаях это вообще так, что A f(); ... A a(f()); Требует фактического вызова конструктора копирования
test.cpp:
#include "noncopyable.hpp" #include <iostream>
using namespace std;
class A : private spectra::noncopyable { public: A() { cout << "Object created" << endl; } // A(const A&) { cout << "Const copy constructor" << endl; } ~A() { cout << "Object destroyed" << endl; } };
A f() { A a; return a; }
int main() { A b = f(); }