希望这不会重复,但无法找到优雅的解决方案。是否可以说特殊基类的子类只能在模板工厂函数中创建?由于简单性,我只想在基类中强制执行此行为。这是一个简单的例子:
template <class T>
T* createBase();
template<typename T>
class Base {
protected:
template <class T>
friend T* createBase();
static T* create()
{
return new T();
}
};
class TestClass1 : public Base<TestClass1>
{
public:
TestClass1() : Base() {}
};
template <class T>
T* createBase()
{
static_assert(std::is_base_of<Base<T>, T>::value, "use the createBase function only for Base<T> subclasses");
return Base<T>::create();
}
实际上这是允许的:
TestClass2 *testClass = createBase<TestClass2>();
TestClass2 tester;
但我只想拥有这个:
TestClass1 *testClass = createBase<TestClass1>(); //allowed
TestClass1 tester; // compile error
当然,我知道我只需要放置TestClass1 private
或protected
的构造函数。但是在Base对象中说它真的很好。
修改
当子类的构造函数是公共的时,编译错误也是一个很好的解决方案。也许使用static_assert()。
答案 0 :(得分:1)
即使使用CRTP,也无法控制基类中构造函数的可访问性。
您可以做的是在基本ctor中添加一个static_assert,检查派生类的T
a.k.a是否没有可公开访问的默认ctor:
template <class T>
class Base {
public:
Base() {
static_assert(!std::is_default_constructible<T>::value,
"T must not be default constructible");
}
};
static_asswert
因类别范围无效,原因如下所示:CRTP std::is_default_constructible not working as expected