在成员变量中保存任何类型的C ++模板类

时间:2011-08-22 23:00:27

标签: c++ templates member

我有两节课。

使用模板构建第一个类(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;
};

这个问题有没有(干净的)解决方案?

- 来自德国的问候,巴斯蒂安

5 个答案:

答案 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;
};

现在,相关费用:

  • 与价值的互动仅限于IA界面;
  • 如果您尝试强制转换以获得真实类型,这意味着您知道真实类型,因此它没有用,并且使A类型的参数变得非常容易使用。
  • 存在与运行时继承关联的运行时成本

优势:

  • 其他开发者很容易理解
  • 它自然地限制了某些特定类型的可能类型
  • 它不使用提升(有时,你不能)

所以要做得更好,还有其他不那么简单的解决方案,但这些解决方案很简单,可以使用:

如果你可以使用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)

是的,它已经完成了。 boost::any

答案 4 :(得分:1)

我认为有助于理解,模板化的类为您使用它的每种类型创建一个全新的单独的类。例如,Vector<int>Vector<float>与类VectorIntVectorFloat分开。

对于B类,您基本上要求value变量为A<int>A<float>,这与您希望值为“A_int”或“A_float”。为了实现这一目标......好吧,使用另一个模板!