我有两节课。
使用模板构建第一个类(A)。
template <class T>
class A
{
public:
T value;
};
第二类(B)应该有一个A类对象作为成员变量。像这样:
class B
{
public:
A<int> value;
};
但现在我想在A类中使用任何类型的模板类。不仅 int 。 显然我不能声明包含任何类的类的(member-)变量。 所以,我需要这样的东西:
class B
{
public:
A<*> value;
};
这个问题有没有(干净的)解决方案?
- 来自德国的问候,巴斯蒂安
答案 0 :(得分:6)
您不能将一个类B
与“任何”成员对象放在一起,因为B
必须是定义明确的类,而A<T>
是不同的类型< / em>适用于不同类型T
。您可以将B
本身设为模板:
template <typename T>
class B
{
A<T> value;
};
或者您可以查看boost::any
,它是任意类型的类型擦除容器(但使用它需要一定量的额外工作)。 any
类仅适用于 value 类型,但并非完全随意。
答案 1 :(得分:3)
最简单的解决方案是将所有A变体从公共接口中删除,即使它是空的:
class IA{}
template <class T>
class A : public IA
{
public:
T value;
};
class B
{
public:
IA* value;
};
现在,相关费用:
优势:
所以要做得更好,还有其他不那么简单的解决方案,但这些解决方案很简单,可以使用:
如果你可以使用boost,boost :: any,boost :: variant和boost :: mpl可能是解决方案的基础。
Boost any可以用作void *的安全替代品。唯一的问题是你可以有任何类型,比如类型是B类的模板参数。
如果您知道A可以使用的所有类型,则可以成功使用Boost变体。
如果您只想设置可能类型的列表并确保您的成员仅适用于它们,则MPL可能会有所帮助。你可以用MPL做很多事情,所以它真的取决于你的确切需求。
答案 2 :(得分:2)
我认为你有两个选择。第一种是通过实例变量的类型参数来参数化您的类:
template <class T> struct B
{
A<T> value;
};
另一种选择是将value
声明为void*
指针。 (但这可能不是你想要的)。
答案 3 :(得分:1)
答案 4 :(得分:1)
我认为有助于理解,模板化的类为您使用它的每种类型创建一个全新的单独的类。例如,Vector<int>
和Vector<float>
与类VectorInt
和VectorFloat
分开。
对于B类,您基本上要求value
变量为A<int>
或A<float>
,这与您希望值为“A_int”或“A_float”。为了实现这一目标......好吧,使用另一个模板!