const, шаблоны и приведение типов. Чего-то я не понимаю
От: Аноним  
Дата: 10.06.11 10:05
Оценка: :)
Есть шаблонный класс с вот таким методом (велосипед для работы с вектором):

template<typename T> class AVector3D {
....
void set ( T &X,  T &Y,  T &Z) {array[1] = X; array[2] = Y; array[3] = Z;}



есть вот такой тестовый пример:


 AVector3D<double> a, q, r;
    double b=3.14;
    q.set(1.0, 1.0, 1.0);
    r.set(1,1,1);

На последнюю строчку ругается как и на предпоследнюю: нет такого метода, который он мог бы вызвать.
Если в объявлении метода поставить const то все компилируется и работает. Хотелось бы понять, что тут не так. Ах да, компилятор — gcc 4.4.5.

Дальше еще хлеще, правда уже сам шаблон не причем. Для данного класса есть перезагруженные методы + и *


   //Умножение скаляра на вектор
    template<typename T> inline AVector3D<T> operator* (T &val, AVector3D<T> &v) {
    AVector3D<T> tempVec = v;
        return tempVec *= val;
    }
        //Сложение векторов
    template<typename T> inline AVector3D<T> operator+ (AVector3D<T> &v1, AVector3D<T> &v2) {
    AVector3D<T> tempVec = v1;
        return tempVec += v2;
    }

и если есть что-то типа такого: a=b+c*d; выпадает в ступор и говорит что нет подходящего оператора присваивания. Если везде const, то проблем нету. Тут скорее всего вопрос почему компилятор, при вычислений выражение создает const-объект, хотя в перегруженном операторе ни одного упоминания const нету.
Re: const, шаблоны и приведение типов. Чего-то я не понимаю
От: Кодёнок  
Дата: 10.06.11 10:24
Оценка:
Здравствуйте, Аноним, Вы писали:

Вместо T& пиши const T&, тогда заработает.
Re: const, шаблоны и приведение типов. Чего-то я не понимаю
От: _niko_ Россия  
Дата: 10.06.11 10:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть шаблонный класс с вот таким методом (велосипед для работы с вектором):


А>
template<typename T> class AVector3D {
А>....
А>void set ( T &X,  T &Y,  T &Z) {array[1] = X; array[2] = Y; array[3] = Z;}
А>



А>есть вот такой тестовый пример:



А>
А> AVector3D<double> a, q, r;
А>    double b=3.14;
А>    q.set(1.0, 1.0, 1.0);
А>    r.set(1,1,1);
А>

А>На последнюю строчку ругается как и на предпоследнюю: нет такого метода, который он мог бы вызвать.
А>Если в объявлении метода поставить const то все компилируется и работает. Хотелось бы понять, что тут не так. Ах да, компилятор — gcc 4.4.5.

А>Дальше еще хлеще, правда уже сам шаблон не причем. Для данного класса есть перезагруженные методы + и *



А>
А>   //Умножение скаляра на вектор
А>    template<typename T> inline AVector3D<T> operator* (T &val, AVector3D<T> &v) {
А>    AVector3D<T> tempVec = v;
А>        return tempVec *= val;
А>    }
А>        //Сложение векторов
А>    template<typename T> inline AVector3D<T> operator+ (AVector3D<T> &v1, AVector3D<T> &v2) {
А>    AVector3D<T> tempVec = v1;
А>        return tempVec += v2;
А>    }
А>

А>и если есть что-то типа такого: a=b+c*d; выпадает в ступор и говорит что нет подходящего оператора присваивания. Если везде const, то проблем нету. Тут скорее всего вопрос почему компилятор, при вычислений выражение создает const-объект, хотя в перегруженном операторе ни одного упоминания const нету.


В строке
q.set(1.0, 1.0, 1.0);
цыфры являются константами, посему если принимать их по ссылке то по константной, метод set нада подкорректировать:


// Или так
    set( T const & X, T const & Y, const & Z) {array[1] = X; array[2] = Y; array[3] = Z;}
// Или так
    set( T X, T Y, Z) {array[1] = X; array[2] = Y; array[3] = Z;}


А по 2-у пункту:
Операторы operator* и operator+ то ты определил, а operator*= и operator+= кто будет определять?
Re[2]: const, шаблоны и приведение типов. Чего-то я не поним
От: quodum  
Дата: 10.06.11 11:03
Оценка: 2 (1) :)
Здравствуйте, _niko_, Вы писали:

__>В строке
__>q.set(1.0, 1.0, 1.0);
__>
цыфры являются константами,


Неверно. У числовых литералов в данном примере тип double (безо всяких const). См. ISO/IEC 14882:2003, 2.13.3.

А с неконстантными ссылками они не могут связываться, потому что являются rvalue.
Re[2]: const, шаблоны и приведение типов. Чего-то я не поним
От: Abesh  
Дата: 10.06.11 13:51
Оценка:
__>В строке
__>q.set(1.0, 1.0, 1.0);
__>
цыфры являются константами, посему если принимать их по ссылке то по константной, метод set нада подкорректировать:


Да, ступил.

__>
__>// Или так
__>    set( T const & X, T const & Y, const & Z) {array[1] = X; array[2] = Y; array[3] = Z;}
__>// Или так
__>    set( T X, T Y, Z) {array[1] = X; array[2] = Y; array[3] = Z;}
__>


__>А по 2-у пункту:

__>Операторы operator* и operator+ то ты определил, а operator*= и operator+= кто будет определять?

Они есть, просто не стал выкладывать, но если надо:


T & operator [ ] (int i) {return array[i];}
AVector3D<T> & operator*= (T &val) {array[0] *= val; array[1] *= val; array[2] *= val; return *this;}
AVector3D<T> & operator+= (Vector3D<T> &v) {array[0] += v[0]; array[1] += v[1]; array[2] += v[2]; return *this;}
Re: const, шаблоны и приведение типов. Чего-то я не понимаю
От: Centaur Россия  
Дата: 10.06.11 16:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть шаблонный класс с вот таким методом (велосипед для работы с вектором):


template<typename T> class AVector3D {
А>....
А>void set ( T &X,  T &Y,  T &Z) {array[1] = X; array[2] = Y; array[3] = Z;}


Зачем объявлять параметр ссылкой на неконстанту, если ты не собираешься его менять? А если ты собираешься его менять, то как ты собираешься менять значение 1.0? Или значение временного объекта, полученного преобразованием значения 1 к типу double?
Re: const, шаблоны и приведение типов. Чего-то я не понимаю
От: stbzh  
Дата: 14.06.11 15:41
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Есть шаблонный класс с вот таким методом (велосипед для работы с вектором):
...
А>и если есть что-то типа такого: a=b+c*d; выпадает в ступор и говорит что нет подходящего оператора присваивания. Если везде const, то проблем нету. Тут скорее всего вопрос почему компилятор, при вычислений выражение создает const-объект, хотя в перегруженном операторе ни одного упоминания const нету.

Прочитайте про перегрузку оператора умножения — если данный оператор является членом класса, то он не может принимать двух аргументов. Минимально причесанный работающий код:

template< typename T >
class AVector3D
{
    T arr[3];
public:
    void set(T& X,  T& Y,  T& Z)
    {
        arr[0] = X;
        arr[1] = Y;
        arr[2] = Z;
    }

    T & operator[] (int i)
    {
        return arr[i];
    }

    AVector3D<T>& operator*= (T& val)
    {
        arr[0] *= val;
        arr[1] *= val;
        arr[2] *= val;
        return *this;
    }

    AVector3D<T>& operator+= (AVector3D<T>& v)
    {
        arr[0] += v[0];
        arr[1] += v[1];
        arr[2] += v[2];
        return *this;
    }

    AVector3D<T> operator* (AVector3D<T>& v)
    {
        AVector3D<T> tempVec = *this;
        return tempVec *= v;
    }

    AVector3D<T> operator+ (AVector3D<T>& v)
    {
        AVector3D<T> tempVec = *this;
        return tempVec += v;
    }
};

template< typename T >
AVector3D<T> operator* (T& val, AVector3D<T>& v)
{
    AVector3D<T> tempVec = v;
    return tempVec *= val;
}

int _tmain( int argc, _TCHAR* argv[] )
{
    AVector3D< double > a, b, c;
    double par1 = 1.0, par2 = 2.0, par3 = 3.0;
    b.set( par1, par2, par3 );
    c.set( par3, par2, par1 );
    double d = 3.14;
    a = b + d*c;

    return 0;
}
Re: const, шаблоны и приведение типов. Чего-то я не понимаю
От: jazzer Россия Skype: enerjazzer
Дата: 15.06.11 01:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Дальше еще хлеще, правда уже сам шаблон не причем. Для данного класса есть перезагруженные методы + и *


Чтоб не иметь проблем и лишней писанины с перегрузкой операторов для твоего класса, пользуйся
http://www.boost.org/libs/utility/operators.htm
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.