当我模板化时,隐含的转换不会发生

时间:2010-12-04 02:44:56

标签: c++ templates type-conversion

这里有几个相关但不同的类。一个包含浮动列表;一个只包含一个。有时我想把这些加在一起。在这种情况下,我想将“非列表”提升为列表。这是代码,它按照我想要的方式工作。

#define LIST_SZ 4

class Vec1;

class Vec1_list {

    public:
        Vec1_list() {}
        Vec1_list(const Vec1& in);

        float x[LIST_SZ];
};

class Vec1 {

    public:
        Vec1() {}
        Vec1(const float& in);

        float x;
};

Vec1::Vec1(const float& in) {
    x = in;
}

Vec1_list::Vec1_list(const Vec1& in) {
    for (int i = 0; i < LIST_SZ; i++) {
        x[i] = in.x;
    }
}

Vec1_list operator*(const Vec1_list& a, const Vec1_list& b) {
    Vec1_list tmp;

    for (int i = 0; i < LIST_SZ; i++) {
        tmp.x[i] = a.x[i]*b.x[i];
    }

    return tmp;
}

int main(void) {
    Vec1 v1;
    Vec1_list v2, v3, answer;

    answer = v1*v3;
}

但现在说我想像这样模板化......

#define LIST_SZ 4

template <typename T> class Vec1;

template <typename T>
class Vec1_list {

    public:
        Vec1_list() {}
        Vec1_list(const Vec1<T>& in);

        T x[LIST_SZ];
};

template <typename T>
class Vec1 {

    public:
        Vec1() {}
        Vec1(const T& in);

        T x;
};

template <typename T>
Vec1<T>::Vec1(const T& in) {
    x = in;
}

template <typename T>
Vec1_list<T>::Vec1_list(const Vec1<T>& in) {
    for (int i = 0; i < LIST_SZ; i++) {
        x[i] = in.x;
    }
}

template <typename T>
Vec1_list<T> operator*(const Vec1_list<T>& a, const Vec1_list<T>& b) {
    Vec1_list<T> tmp;

    for (int i = 0; i < LIST_SZ; i++) {
        tmp.x[i] = a.x[i]*b.x[i];
    }

    return tmp;
}

int main(void) {
    Vec1<float> v1;
    Vec1_list<float> v2, v3, answer;

    answer = v1*v3;
}

'mult'导致编译器此次窒息 - 它不会自动调用我的Vec1 - &gt; Vec1_list构造函数。这是C ++生活中的事实,还是有一些方法可以用来让它自动发生?另一种选择是,我需要从功能中获得巨大的支持。

3 个答案:

答案 0 :(得分:1)

模板参数扣除不考虑通过转换构造函数进行的用户定义转换。

模板推导尝试找到使参数化类型相同的函数模板参数替换为参数类型。当它不能时,允许(我在这里简化):const / volatile限定修改或'派生到base'指针转换。

标准[temp.deduct.call]的第14.8.2.1/3节对此进行了描述。

答案 1 :(得分:1)

您必须将operator*声明为Vec1_list类的朋友,以便在实例化Vec1_list时对其进行实例化,然后执行转换。

编辑: 为此,请将operator *定义移动到Vec1_list类模板声明:

friend static Vec1_list operator*(const Vec1_list& a, const Vec1_list& b){
    /* ... */
}

答案 2 :(得分:0)

我不知道为什么它没有推广到所需的Vec1_list。但如果不可能,那么总能做到这一点:

template <typename T>
Vec1_list<T> operator*(const Vec1<T>& a, const Vec1_list<T>& b) {

    return Vec1_list<T>(a)*b;;
}

顺便说一下,我还在挖掘原来的问题。