Trying to create a std::shared_ptr
of an object which takes a std::shared_ptr
as a parameter resulted in a "no matching constructor for initialization of 'object'" compile error.
My code looks as following:
// Sidebar Widgets
_widgets.sideBarWidgetLeft = std::make_shared<SideBarWidget>();
_widgets.sideBarWidgetLeft->hide();
_widgets.sideBarWidgetRight = std::make_shared<SideBarWidget>();
_widgets.sideBarWidgetRight->hide();
// Pointer Test
CalibrationManagementWidget* test = new CalibrationManagementWidget( _widgets.sideBarWidgetLeft, 0 );
// Sidebar Left
_widgets.calibrationManagementWidget = std::make_shared<CalibrationManagementWidget>( _widgets.sideBarWidgetLeft, 0 );
_widgets.calibrationManagementWidget->hide();
_widgets.cameraWidget = std::make_shared<CameraWidget>( 0, VISUALISATION_TYPE_NORMAL );
_widgets.cameraWidget->hide();
While "Pointer Test" compiles just fine, the lines under "Sidebar Left" create named error. Is there something I'm doing wrong instantiating or isn't this possible in general?
Here is (one of) the error message(s):
/usr/include/c++/5.4.0/ext/new_allocator.h:120: Error: no matching constructor for initialization of 'CalibrationManagementWidget'
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
EDIT:
As requested I'll post some snippets which contain also the constructor of the CalibrationWidget.
calibrationwidget.h
...
Q_INVOKABLE CalibrationManagementWidget(QWidget* parent = 0 , VisualisationType visuType = VISUALISATION_TYPE_TRANSLATOR);
CalibrationManagementWidget( std::shared_ptr<SideBarWidget> sideBarWidget, QWidget* parent = 0 );
virtual ~CalibrationManagementWidget();
...
calibrationwidget.cpp
...
CalibrationManagementWidget::CalibrationManagementWidget(QWidget* parent, enum VisualisationType visuType) : CommonWindowWidget( WIDGET_TYPE_3D, "", "Calibration Management", 0, Ui::UI_WINDOW_FLAG_CLOSABLE, 0, parent, visuType) {
_currentMessage = 0;
_selectedCalibrationType = CALIBRATION_TYPE_UNKNOWN;
_messageEventLoop = new QEventLoop(this);
_updateTimer = new QTimer();
setupUi();
}
CalibrationManagementWidget::CalibrationManagementWidget(std::shared_ptr<SideBarWidget> sideBarWidget, QWidget* parent) : CommonWindowWidget( WIDGET_TYPE_3D, "", "Calibration Management", 0, Ui::UI_WINDOW_FLAG_CLOSABLE, sideBarWidget, parent) {
_currentMessage = 0;
_selectedCalibrationType = CALIBRATION_TYPE_UNKNOWN;
_messageEventLoop = new QEventLoop(this);
_updateTimer = new QTimer();
setupUi();
}
CalibrationManagementWidget::~CalibrationManagementWidget() {
delete _messageEventLoop;
_messageEventLoop = 0;
delete _updateTimer;
_updateTimer = 0;
}
...
Here are also snippets from the CommonWindowWidget.
commonwindowwidget.h
...
CommonWindowWidget(WidgetType widgetType, const QString& headerTitle = "Foldable Widget", const string& pageName = "Foldable Widget", unsigned int view = 0, unsigned int uiWindowFlags = 0, std::shared_ptr<SideBarWidget> sideBarWidget = 0, QWidget* parent = 0, VisualisationType visuType = VISUALISATION_TYPE_NORMAL);
virtual ~CommonWindowWidget();
...
commonwindowwidget.cpp
...
CommonWindowWidget::CommonWindowWidget(WidgetType widgetType, const QString& headerTitle, const string& pageName, unsigned int view, unsigned int uiWindowFlags, std::shared_ptr<SideBarWidget> sideBarWidget, QWidget* parent, VisualisationType visuType) : CommonStackedWidget(widgetType, pageName, view, parent, visuType) {
_windowFlags = uiWindowFlags;
_sideBarWidget = std::move(sideBarWidget);
setupUi();
_ui.headerWidget->headerLabel()->setText( headerTitle );
connect( _ui.headerWidget, SIGNAL(headerDoubleClicked()), this, SLOT(changeFoldState()));
connect( _ui.headerWidget, SIGNAL(changeFoldStateClicked()), this, SLOT(changeFoldState()));
connect( _ui.headerWidget, SIGNAL(closeClicked()), this, SLOT(navigateToHome()));
}
CommonWindowWidget::~CommonWindowWidget() {
}
...
When forwarded, 0 causes the parameter to be deduced as int
, which is not convertible to a pointer anymore.
Only the literal 0 can represent a pointer, but after having been passed to make_shared
, the literal becomes the int
value 0, which causes the error, as the constructor expects a pointer.
Use nullptr
instead:
_widgets.calibrationManagementWidget =
std::make_shared<CalibrationManagementWidget>(
_widgets.sideBarWidgetLeft, nullptr
);
This is the main reason why nullptr
was introduced.
Explanation: https://channel9.msdn.com/Shows/Going+Deep/Stephan-T-Lavavej-Everything-you-ever-wanted-to-know-about-nullptr, about minute 28:00.