Неявное преобразование не происходит при шаблонизации - PullRequest
4 голосов
/ 04 декабря 2010

Вот пара связанных, но разных классов.Один содержит список поплавков;один содержит только один.Иногда я хочу, скажем, умножить их вместе.В этом случае я хочу «продвинуть» не-список в список.Вот код, который работает так, как я хочу.

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

'Мульт'вызывает компилятор на этот раз - он не будет автоматически вызывать мой конструктор Vec1 -> Vec1_list.Это факт жизни в C ++, или есть какой-то метод, который я могу использовать, чтобы это произошло автоматически?Альтернатива в том, что мне нужен огромный поклонник из функций.

Ответы [ 3 ]

1 голос
/ 04 декабря 2010

Ваше пользовательское преобразование через конструктор преобразования не учитывается при выводе аргумента шаблона.

При выводе шаблона делается попытка найти замену параметров шаблона функции, которые делают параметризованный тип идентичным к типам аргументов.Когда это невозможно, это разрешается (я упрощаю здесь): изменение квалификации const / volatile или преобразование указателя «выведено в основание».

Это описано в разделе 14.8.2.1/3 стандарта.[temp.deduct.call].

1 голос
/ 09 декабря 2010

Вы должны объявить operator* как друга класса Vec1_list, чтобы он был создан при создании экземпляра Vec1_list, а затем будет выполнено преобразование.

РЕДАКТИРОВАТЬ: Вдля этого переместите определение оператора * в объявление шаблона класса Vec1_list:

friend static Vec1_list operator*(const Vec1_list& a, const Vec1_list& b){
    /* ... */
}
0 голосов
/ 04 декабря 2010

Я не знаю, почему это не способствует достижению желаемого Vec1_list.Но если это невозможно, то всегда можно сделать следующее:

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

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

Кстати, я до сих пор копаю оригинальную проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...