简体   繁体   English

具有模板成员的模板类的模板类型推导

[英]Template type deduction of template class with template member

Lets say I have following (rather confusing example from Bjarne Stroustrup's book) template class with template member 可以说我有下面的模板类(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); is one way to create object of this class, but is Scalar deduced as float or T is deduced as float in this example? 是创建此类对象的一种方法,但是在此示例中, Scalar推导为float还是T推导为float? What are some different ways to create objects of this class? 创建此类的对象有哪些不同的方法? I want to understand how template type is being deduced from these examples. 我想了解如何从这些示例中推断出模板类型。
  2. What is the use of member templates? 成员模板的用途是什么?

complex<float> cf(0,0); is one way to create object of this class, but is Scalar deduced as float or T is deduced as float in this example? 是创建此类对象的一种方法,但是在此示例中, Scalar推导为float还是T推导为float What are some different ways to create objects of this class? 创建此类的对象有哪些不同的方法? I want to understand how template type is being deduced from these examples. 我想了解如何从这些示例中推断出模板类型。

In this example, nothing is deduced. 在此示例中,没有任何推断。 Scalar is explicitly specified as float . Scalar明确指定为float

The template constructor does not get called for this. 模板构造函数不会为此被调用。

What is the use of member templates? 成员模板的用途是什么?

Say you have: 说您有:

Complex<float> c1(10, 20);

and then you want to use c1 to create another Complex but with a different type for Scalar . 然后您要使用c1创建另一个ComplexScalar类型不同。

Complex<double> c2(c1);

In this case the template constructor is used. 在这种情况下,使用模板构造函数。 Scalar is explicitly specified as double and T is deduced as float . 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

What's being demonstrated is deduction of a member function template parameter from the template type of a parameter. 演示的是从参数的模板类型中推导出成员函数模板参数。

For s2d above, we know that Outer is double, it's specified not deduced. 对于上面的s2d ,我们知道Outer是double,未指定为推断。

However when we pass s2f to its constructor we are passing an object of type S2. 但是,当我们将s2f传递给它的构造函数时,我们传递的是S2类型的对象。 We provide a constructor that takes S2<? Inner ?> 我们提供了一个采用S2<? Inner ?> S2<? Inner ?> , so we have a container match if we deduce Inner to be float. S2<? Inner ?> ,因此如果推断Inner为浮点型,则我们有一个容器匹配项。

What's being demonstrated is a templated class with further templated member functions. 正在演示的是带有更多模板化成员函数的模板化类。 Consider: 考虑:

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

If we do 如果我们这样做

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

Here the copy constructor deduces Inner to be not just int but S<int> . 在这里,复制构造函数推论Inner不仅是int而且是S<int>

Practical use: 实际使用:

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

In your example, the code explicitly specifies Scalar to be float (no deduction happens). 在您的示例中,代码将Scalar明确指定为float (不进行扣除)。 But the copy(ish) constructor you show is not the one that will be called in your subsequent example. 但是您显示的copy(ish)构造函数不是在后续示例中将被调用的构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM