使用模板成员

时间:2015-06-23 16:28:31

标签: c++ templates

让我说我有跟随(比较困惑的例子来自Bjarne Stroustrup的书)模板类的模板成员

template<class Scalar> class complex {
    Scalar re, im;
public:
        template<class T>
        complex(const complex<T> &c) : re(c.re), im(c.im) {}
        //...
}
  1. complex<float> cf(0,0);是创建此类对象的一种方法,但是Scalar推导为float或T在此示例中推导为float?有什么不同的方法来创建这个类的对象?我想了解如何从这些示例推导出模板类型。
  2. 会员模板的用途是什么?

3 个答案:

答案 0 :(得分:1)

  

complex<float> cf(0,0);是创建此类对象的一种方法,但在此示例中推导出Scalar floatT推导为float?有什么不同的方法来创建这个类的对象?我想了解如何从这些示例推导出模板类型。

在这个例子中,没有任何推断。 Scalar明确指定为float

不会为此调用模板构造函数。

  

会员模板的用途是什么?

说你有:

Complex<float> c1(10, 20);

然后您想使用c1创建另一个Complex,但Scalar的类型不同。

Complex<double> c2(c1);

在这种情况下,使用模板构造函数。 Scalar明确指定为doubleT推断为float

答案 1 :(得分:1)

template<class Outer>
struct S1 {
    template<class Inner>
    S1(const S1<Outer>& rhs) {}
};

template<class Outer>
struct S2 {
    template<class Inner>
    S2(const S2<Inner>& rhs) {}
};

S1<float> s1f;
S2<float> s2f;

S1<double> s1d(s1f); // error
S2<double> s2d(s2f); // ok

正在演示的内容是从参数的模板类型中扣除成员函数模板参数。

对于上面的s2d,我们知道Outer是双倍的,指定的不是推断的。

然而,当我们将s2f传递给它的构造函数时,我们传递的是S2类型的对象。我们提供了一个带S2<? Inner ?>的构造函数,因此如果我们推导Inner为浮点数,我们就会有一个容器匹配。

正在演示的内容是一个带有进一步模板化成员函数的模板类。考虑:

template<class Outer>
struct S {
    template<class Other>
    S(const Other& rhs) {}
};

如果我们这样做

S<float> sf;
S<int> si(sf);

此处复制构造函数推导Inner不仅仅是int而是S<int>

实际使用:

template<class C, class T>
struct PtrContainer {
    using container_type = C;
    using value_type = T;
    using self_type = PtrContainer<container_type, value_type>;
    using ptr_type = T*;
    using size = sizeof(T);

    PtrContainer() : c() {}

    void append(ptr_type p) {
        c.push_back(p);
    }

    template<class D>
    std::enable_if<std::is_base_of<T, D>::value, void>::type
    transfer(PtrContainer<D>& rhs) {
        c.insert(c.end(), rhs.c.begin(), rhs.c.end());
        rhs.c.clear();
    }

    void clear() {
        for (auto* ptr: c) {
            delete ptr;
        }
        c.clear();
    }

    ~PtrContainer() { clear(); }

    container_type<ptr_type> c;
};

struct S {};
struct SD : public S {};

int main() {
    PtrContainer<vector, S> pvs;
    pvs.append(new S);
    PtrContainer<list, SD> plsd;
    plsd.append(new SD);
    pcs.transfer(plsd);
}

答案 2 :(得分:0)

在您的示例中,代码明确指定Scalarfloat(不会发生扣减)。但是您显示的副本(ish)构造函数不是将在后续示例中调用的构造函数。