Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查子类的构造函数在C+中是否为public+;_C++_Templates_C++11_Compiler Errors_Metaprogramming - Fatal编程技术网

C++ 检查子类的构造函数在C+中是否为public+;

C++ 检查子类的构造函数在C+中是否为public+;,c++,templates,c++11,compiler-errors,metaprogramming,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* crea

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

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();
}
模板
T*createBase();
模板
阶级基础{
受保护的:
模板
朋友T*createBase();
静态T*create()
{
返回新的T();
}
};
类TestClass1:公共基
{
公众:
TestClass1():Base(){}
};
模板
T*createBase()
{
static_assert(std::is_base_of::value,“仅对基本子类使用createBase函数”);
返回Base::create();
}
实际上这是允许的:

TestClass2 *testClass = createBase<TestClass2>();
TestClass2 tester;
TestClass2*testClass=createBase();
TestClass2测试仪;
但我只想要这个:

TestClass1 *testClass = createBase<TestClass1>(); //allowed
TestClass1 tester; // compile error
TestClass1*testClass=createBase()//允许
TestClass1测试仪;//编译错误
当然,我知道我只需要将TestClass1的构造函数
private
设置为protected
。但是在基本对象中这样说会很好

编辑:


当子类的构造函数为public时出现编译错误也是一个很好的解决方案。可能使用静态断言()。

即使使用CRTP,也无法从基类控制构造函数的可访问性

您可以做的是在基本构造函数中添加一个静态断言,检查派生类的
T
a.k.a是否没有可公开访问的默认构造函数:

template <class T>
class Base {
public:
    Base() {
        static_assert(!std::is_default_constructible<T>::value,
                      "T must not be default constructible");
    }
};
模板
阶级基础{
公众:
Base(){
静态断言(!std::是默认值\u可构造的::值,
“T不能是默认可构造的”);
}
};

static\u asswert
在类作用域上不起作用,原因如下:

我当然可以这样做,但我想在基类中强制这种行为。如果没有工厂方法,用户不应该能够创建Base类型的对象。因此,我如何强制用户将构造函数设置为private或protected.idk,我完全延迟了,无法使
static\u assert
工作。我会在头脑清醒后回来的,比如?我猜您只是在类范围内尝试了
static\u assert
,但由于我不完全确定的原因,它不起作用。可能与
friend
声明有关。@TartanLlama我也像你一样在ctor中尝试过,因为它在类级别上不起作用。我很困惑,因为我保留了旧代码,它看起来不太管用。还有一个让我困惑的想法。当我将TestClass1的ctor设置为私有或受保护时。如何使我的对象可访问函数createBase();?我发布了一个新问题: