【发布时间】:2023-03-25 23:34:01
【问题描述】:
我偶然发现了一个场景,我正在尝试找出最干净的方法,如果有的话。
我有一个带有受保护构造函数的模板类,它需要由朋友模板类实例化。两者共享部分模板参数,但不是全部。这是我的问题的一个例子。
我想从有经验的程序员那里知道是否有其他可能的解决方案(我想没有,除了将构造函数公开),如果在这两者之间,我提出的一个比另一个更容易接受。 谢谢
解决方案 1- 我向具有受保护构造函数(元素类)的类提供“不必要的”模板参数。
template <typename Tp_>
class Engine_Type_X
{
};
template <typename Tp_>
class Engine_Type_Z
{
};
//Forward declaration
template <typename Tp_, template<typename> typename Eng_>
class Container;
//Eng_ is only required to declare the friend class
template <typename Tp_,template<typename> typename Eng_>
class Element
{
friend class Container<Tp_,Eng_>;
Tp_ tp_;
protected:
Element(Tp_ tp) : tp_{tp} //protected ctor!!!
{}
};
template <typename Tp_, template<typename> typename Eng_>
class Container
{
using Element_tp = Element<Tp_,Eng_>;
using Engine_tp = Eng_<Tp_>;
std::vector<Element_tp> container_;
Engine_tp &engine_;
public:
Container(Engine_tp &engine) : container_{},engine_{engine}
{}
void install(Tp_ tp)
{ Element_tp elem{tp};
container_.emplace_back(elem);
}
};
解决方案 2 - 我使用的方法类似于我在此处找到的方法 How to declare a templated struct/class as a friend?
template <typename Tp_>
class Engine_Type_X
{
};
template <typename Tp_>
class Engine_Type_Z
{
};
template <typename Tp_>
class Element
{
template<typename,template<typename>typename> friend class Container; //All templated classes are friend
Tp_ tp_;
protected:
Element(Tp_ tp) : tp_{tp} //protected ctor!!!
{}
};
template <typename Tp_, template<typename> typename Eng_>
class Container
{
using Element_tp = Element<Tp_>;
using Engine_tp = Eng_<Tp_>;
std::vector<Element_tp> container_;
Engine_tp &engine_;
public:
Container(Engine_tp &engine) : container_{},engine_{engine}
{}
void install(Tp_ tp)
{ Element_tp elem{tp};
container_.emplace_back(elem);
}
};
【问题讨论】:
-
两者有不同的含义。在第一个中只有
Container<Tp_,Eng_>;是Element<Tp_,Eng_>的朋友在第二个中任何Container是任何Element的朋友,选择你需要的。 -
在您的情况下,另一种选择可能是将
Element声明为Container的内部类(不确定这将如何适合您的整体设计)。 -
使用第二个。
Engine逻辑上是Container的详细信息,因此将其放在Element的签名中是没有意义的。