限制variadic模板类中的构造函数访问

restrict constructor access in variadic template class

本文关键字:构造函数 访问 variadic 限制      更新时间:2023-10-16

我想创建一个静态检查的生成器。大致如下:

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
}

不同的类模板专业化是完全独立的类,不能访问彼此的内部。幸运的是,总有朋友可以拯救你的一天。

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<>();
}