I'm getting some compiling errors when creating constructors for my derived image classes while using PImpl Idiom and Curiously Recurring Template Pattern. The base class for image class implementations uses CRTP (Curiously Recurring Template Pattern) to enforce static dispatch instead of layering on another virtual call. Please tell me what I'm doing wrong. Please see the comments for where the errors occur
// Error: no matching constructor for initialization of 'jpeg_image::impl' [clang-diagnostic-error]
// Error: field has incomplete type 'jpeg_image::impl' [clang-diagnostic-error]
image.hpp
#include <memory>
#include <vector>
namespace image_wrapper {
class image {
public:
//ToDo: declare pure virtual functions
};
class jpeg_image final : public image {
class impl;
std::unique_ptr<impl> _impl;
public:
// Destructor and constructor for reading from a buffer of encoded_bytes
~jpeg_image();
jpeg_image(std::vector<uint8_t> encoded_bytes);
};
} //namespace image_wrapper
image.cpp
#include "image.hpp"
#include <boost/gil.hpp>
#include <functional>
namespace image_wrapper {
namespace {
template <class Derived>
class impl_base {
public:
// ToDo: implement base class functions
protected:
// Constructor
explicit impl_base(std::vector<uint8_t> encoded_bytes) :
_unencoded_image{ std::bind(&impl_base<Derived>::initialize_unencoded_image, this) }, _encoded_bytes{ encoded_bytes }
{
}
private:
boost::gil::rgb8_image_t initialize_unencoded_image() { return static_cast<Derived&>(*this).decode_bytes(); }
boost::gil::rgb8_image_t _unencoded_image;
std::vector<uint8_t> _encoded_bytes;
};
} // namespace
/*
* JPEG Class Definitions
*/
class jpeg_image::impl : public impl_base<jpeg_image::impl> {
public:
// Error: field has incomplete type 'jpeg_image::impl'
jpeg_image::impl(std::vector<uint8_t> encoded_bytes) : impl_base<jpeg_image::impl>(encoded_bytes) {}
boost::gil::rgb8_image_t decode_bytes()
{
// ToDo: implement decode_bytes()
}
};
// Error: no matching constructor for initialization of 'jpeg_image::impl' [clang-diagnostic-error]
jpeg_image::jpeg_image(std::vector<uint8_t> encoded_bytes) : _impl(new jpeg_image::impl(encoded_bytes)) {}
// Jpeg Image Destructor
jpeg_image::~jpeg_image() = default;
} // namespace image_wrapper