C ++模板类和构造函数中的init

时间:2011-07-07 13:14:02

标签: c++ templates typedef typename class-constructors

我有一个模板类,Foo:

template <class A, class B>
class Foo
{
public:
    Foo(A &aInstance);

private:
    Attr<Foo> _attr;
};

然后我有另一个名为Attr的模板类,它是我的Foo类的一个属性,它将Foo类本身作为模板参数。

template <class C>
class Attr
{
    class SomeType
    {
        SomeType();
        ~SomeType();
    };

    Attr(const SomeType* st);
    ~Attr();

private:
    Attr();
}

我想在构造函数中初始化_attr(类型为Attr),将模板中的第一个参数转换为SomeType。

Foo构造函数实现:

template<class A, class B>
Foo<A, B>::Foo(A &aInstance):
    _attr(
        (Attr<Foo<A, B> >::SomeType *) aInstance)
{

}

这不会编译:

错误:')'令牌

之前的预期主要表达式

该错误指的是Foo构造函数实现中的强制转换,就好像SomeType未被识别一样。

我现在有一个实例,但仍然遇到同样的错误。

5 个答案:

答案 0 :(得分:2)

template<class A, class B>
Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) A)
{

}

A是一种类型,您尝试将其传递给构造函数。你需要一个实例。

答案 1 :(得分:1)

0)

(Attr<Foo<A, B> >::SomeType *) A)

此时,A是一个类型名称,即类型的名称,因此,不是您可以投射的任何内容。

1)

此外,Foo<A,B>依赖于AB,因此,Attr<Foo<A, B> >也是一个依赖名称。因此,您需要typename,以便告诉编译器SomeType是一个类型:

(typename Attr<Foo<A, B> >::SomeType *) somePointer)

2)

此外,在C ++中,通常更喜欢C ++ - 演员而不是C风格的演员表。你会发现很多错误。另请参阅this tutorial:)

3)

另一方面:你确定你需要设计演员表,还是Attr指向Foo<A, B>

答案 2 :(得分:1)

首先,Attr类没有(在你的代码片段中)使用C类型,所以你应该解释它的使用位置,以及C和SomeType之间的关系。

第二,在这一行

Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) A)

A是类型而不是对象。如果_attr应该用Foo对象本身初始化,那么你应该传递指针。

Foo<A, B>::Foo():
    _attr(
        (Attr<Foo<A, B> >::SomeType *) this)

但是,就这一点而言,还没有构造Foo对象,所以要小心你在Attr构造函数中用指针做什么。

答案 3 :(得分:0)

尝试将构造函数更改为:

template<class A, class B>
Foo<A, B>::Foo(A &aInstance):
    _attr(
        (typename Attr<Foo<A, B> >::SomeType *) &aInstance) {}

你会,因为你想要一个指针,需要添加一个address-of运算符才能获取实例对象的地址......否则aInstance将不是指针类型,而是它将是引用类型实际上与传递对象本身(通过引用)相同,而不是指向对象的指针。

答案 4 :(得分:0)

这对我有用。一些typedef有助于更轻松地理解模板化代码:

template<class C>
class Attr
{
public:
    class SomeType
    {
        SomeType();
       ~SomeType();
    };

    typedef typename Attr<C>::SomeType ReachIntoSomeType;

    Attr(const SomeType* st) { }
    ~Attr() { }

private:
    Attr();
};

template <class A, class B>
class Foo
{
public:
    Foo(A &aInstance) : _attr(reinterpret_cast<AttrOfFoo::ReachIntoSomeType*>(aInstance))     
    { }

private:
    typedef Attr<Foo> AttrOfFoo;
    AttrOfFoo _attr;
};