模板类的模板类型推导与模板成员

Template type deduction of template class with template member

本文关键字:成员 类型      更新时间:2023-10-16

假设我有以下(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推导为浮点数还是T推导为浮点数?创建此类对象的不同方法有哪些?我想了解如何从这些示例中推断出模板类型。
  2. 成员模板有什么用?

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

在此示例中,不会推断任何内容。 Scalar被显式指定为 float

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

成员模板有什么用?

假设您有:

Complex<float> c1(10, 20);

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

Complex<double> c2(c1);

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

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);
}

在您的示例中,代码显式指定要float Scalar(不发生扣除(。但是您显示的 copy(ish( 构造函数不是将在后续示例中调用的构造函数。