限制可变参数模板类中的构造函数访问权限

时间:2018-07-26 18:13:32

标签: c++ variadic-templates

我想创建一个静态检查的构建器。遵循以下原则:

class HasDough;
class HasCheese;

template <typename ... CurrentTypes>
class Pizza {
    public:
        friend Pizza<> startPizzaMaking();

        Pizza<HasDough, CurrentTypes ...> addDough(){
            return Pizza<HasDough, CurrentTypes ...>();
        }

        Pizza<HasCheese, CurrentTypes ...> addCheese(){
            return Pizza<HasCheese, CurrentTypes ...>();
        }

    public: // I want to change to private
        Pizza() = default;
};


Pizza<> startPizzaMaking() {
    return Pizza<>();
}

像这样使用它:

int main(){
    auto pizza = startPizzaMaking()
        .addDough()
        .addCheese();

    return 0;
}

现在,我可以分开查看当前类型。这样,我可以确保所有内容都已添加。

我的问题是: 我创建新的构建器实例并希望传递当前状态的每一步。为此,构造函数应该是私有的,我将使用friend函数来获取新的构造器。

如何限制对构造函数的访问以强制其他人使用工厂,但在内部仍然可以使用它?

[更新]

简单地将构造函数设为私有是行不通的。该代码将扩展为以下内容:

Pizza<HasDough>::addCheese() {
    return Pizza<HasCheese, HasDough>(); // fine with public constructor, not so with private
}

1 个答案:

答案 0 :(得分:2)

不同的类模板专业是完全独立的类,彼此之间没有内部访问权限。幸运的是,总是有朋友来拯救您的一天。

template <typename ... CurrentTypes>
class Pizza {
    public:
        friend Pizza<> startPizzaMaking();

        Pizza<HasDough, CurrentTypes ...> addDough(){
            return Pizza<HasDough, CurrentTypes ...>();
        }

        Pizza<HasCheese, CurrentTypes ...> addCheese(){
            return Pizza<HasCheese, CurrentTypes ...>();
        }

    private: // OK
        Pizza() = default;

        friend Pizza<> startPizzaMaking();    
        // make every specialisation a friend of every other      <=== this here trick
        template <typename ...> friend class Pizza; 
};

Pizza<> startPizzaMaking() {
    return Pizza<>();
}