Change the definition of Base to take the handle type as a second parameter to avoid the circular dependency.
struct WidgetHandle {};
template <typename TWrapper, typename HandleType>
class Base
{
public:
typedef HandleType value_type;
Base(HandleType value_)
: value(value_) {}
HandleType value;
};
class Widget : public Base<Widget, WidgetHandle>
{
public:
Widget(WidgetHandle value_) : Base(value_) {}
};
int main(int argc, char* argv[])
{
Widget i(WidgetHandle());
return 0;
}
You could also use a traits class to get the WidgeHandle type for Widget.
struct WidgetHandle {};
class Widget;
template<class T>
struct Handle
{
};
template<>
struct Handle<Widget>
{
typedef WidgetHandle type;
};
template <typename TWrapper, typename HandleType = Handle<TWrapper>::type>
class Base
{
public:
typedef HandleType value_type;
Base(HandleType value_)
: value(value_) {}
HandleType value;
};
class Widget : public Base<Widget>
{
public:
Widget(WidgetHandle value_) : Base(value_) {}
};
int main(int argc, char* argv[])
{
Widget i(WidgetHandle());
return 0;
}