检查子类的构造函数是否在C ++中是公共的

时间:2016-01-21 11:52:06

标签: c++ templates c++11 compiler-errors metaprogramming

希望这不会重复,但无法找到优雅的解决方案。是否可以说特殊基类的子类只能在模板工厂函数中创建?由于简单性,我只想在基类中强制执行此行为。这是一个简单的例子:

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 privateprotected的构造函数。但是在Base对象中说它真的很好。

修改

当子类的构造函数是公共的时,编译错误也是一个很好的解决方案。也许使用static_assert()。

1 个答案:

答案 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