PImpl Idiom と Curiously Recurring Template Pattern を使用しているときに派生イメージ クラスのコンストラクターを作成すると、コンパイル エラーが発生します。画像クラス実装の基本クラスは、CRTP (Curiously Recurring Template Pattern) を使用して、別の仮想呼び出しを階層化する代わりに静的ディスパッチを強制します。私が間違っていることを教えてください。エラーが発生した場所についてはコメントを参照してください
// エラー: 'jpeg_image::impl' の初期化に一致するコンストラクターがありません [clang-diagnostic-error]
// エラー: フィールドの型が不完全です 'jpeg_image::impl' [clang-diagnostic-error]
画像.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
画像.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