There are 3 classes:
decoder_mqtt
- Common decoder
subdecoder_mqtt_base
- Base subdecoder for each concrete version (not an abstract class, but have virtual method).
subdecoder_mqtt_v5 : subdecoder_mqtt_base
- Derived from subdecoder_mqtt_base
subdecoder class.
decoder_mqtt
creates a subdecoder:
// file: mqtt.cc
#include "mqtt_v5.h"
...
using subdecoder_ptr = std::unique_ptr<subdecoder_mqtt_base>;
...
decoder_base::result_t decoder_mqtt::decode_data(const char* data, size_t length)
{
return subdecoder_put_data<subdecoder_mqtt_v5>(
data, length, SUBDECODERS_STATE::V5_REJECTED, _sd_mqtt_v5 );
}
...
template <class SUBDECODER_T>
decoder_base::result_t decoder_mqtt::subdecoder_put_data(
const char* data, size_t length,
SUBDECODERS_STATE sd_state_if_rejected, subdecoder_ptr& subdecoder)
{
if (!(to_underlying(sd_state_if_rejected) & _subdecoders_state))
{
if (!subdecoder)
subdecoder = std::make_unique<SUBDECODER_T>(this); // Error here!
result_t res = subdecoder->reassemble_and_decode_data(data, length);
if (!res)
{
_subdecoders_state |= to_underlying(sd_state_if_rejected);
subdecoder = nullptr;
}
return res;
}
return result_t(false, 0);
}
Definition of a subdecoder_mqtt_v5
:
class subdecoder_mqtt_v5 : subdecoder_mqtt_base
{
public:
subdecoder_mqtt_v5(decoder_mqtt* d_mqtt);
virtual ~subdecoder_mqtt_v5();
virtual result_t reassemble_and_decode_data(const char* data, size_t length) override final;
....
};
GCC prints an error:
error: no match for ‘operator=’ (operand types are ‘decoder_mqtt::subdecoder_ptr’ {aka ‘std::unique_ptr<subdecoder_mqtt_base>’} and ‘std::_MakeUniq<subdecoder_mqtt_v5>::__single_object’ {aka ‘std::unique_ptr<subdecoder_mqtt_v5, std::default_delete<subdecoder_mqtt_v5> >’})
/usr/include/c /9/bits/unique_ptr.h:305:7: note: candidate: ‘std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = subdecoder_mqtt_base; _Dp = std::default_delete<subdecoder_mqtt_base>]’
305 | operator=(unique_ptr&& __u) noexcept
| ^~~~~~~~
/usr/include/c /9/bits/unique_ptr.h:305:30: note: no known conversion for argument 1 from ‘std::_MakeUniq<subdecoder_mqtt_v5>::__single_object’ {aka ‘std::unique_ptr<subdecoder_mqtt_v5, std::default_delete<subdecoder_mqtt_v5> >’} to ‘std::unique_ptr<subdecoder_mqtt_base>&&’
305 | operator=(unique_ptr&& __u) noexcept
What am I doing wrong? Elsewhere, similar code compiles.
CodePudding user response:
What am I doing wrong?
subdecoder_mqtt_v5
privately derives from subdecoder_mqtt_base
, so there is only an implicit conversion of pointers in the members and friends of subdecoder_mqtt_v5
. The unique_ptr
constructor is not one of those places.
You probably meant to publicly inherit:
class subdecoder_mqtt_v5 : public subdecoder_mqtt_base