2015-03-13 6 views
0

Я пытаюсь изучить шаблоны выражений на C++. Я пытаюсь создать класс для 3D-вектора (в основном вектор размера 3) для хранения координат, пространственных векторов, сил и т. Д., Которые в основном имеют три компонента.Как оценивать выражение при объявлении переменной (в шаблонах выражений)

До сих пор я только реализовал класс для выполнения суммирования двух векторов. Код работает нормально, если я пишу vector3d z; z = x + y;. То есть если я сначала объявляю z переменной, а затем выполняю добавление. Однако я получаю ошибку, когда пытаюсь написать vector3d z = x + y; в одном предложении. Я получаю error: conversion from 'const ExprSum<vector3d, vector3d>' to non-scalar type 'vector3d' requested vector3d z_new = x + y ;

Как реализовать, чтобы иметь возможность использовать = во время объявления переменной?

Ниже мой полный код:

#include <iostream> 
#include <vector> 
#include <cassert> 

using namespace std; 

/** @brief The base expression class */ 

template <class A> 
class Expr{ 
public: 
    typedef std::vector<double>     container_type; 
    typedef typename container_type::size_type size_type; 
    typedef typename container_type::value_type value_type; 
    typedef typename container_type::reference reference; 

    size_type size() const {return static_cast<A const&>(*this).size(); } 
    value_type operator [] (size_t i) const {return static_cast<A const&> (*this)[i];} 
    operator A&()    { return static_cast<  A&>(*this); } 
    operator A const&() const { return static_cast<const A&>(*this); } 
}; 


/** @brief The vector3d class : The vector<double> with 3 elements */ 

class vector3d : public Expr<vector3d> { 
private: 
    container_type _data; 
public: 
    vector3d():_data(3){} 
    vector3d(const vector3d& _rhs){ 
     *this = _rhs; 
    } 

    size_type size() const { return _data.size(); } // should return 3. 

    reference operator [] (size_type i){ 
    assert(i < _data.size()); 
    return _data[i]; 
    } 

    value_type operator [] (size_type i) const { 
    assert(i < _data.size()); 
    return _data[i]; 
    } 

    template <class A> 
    void operator = (const Expr<A>& _rhs){ 
    _data.resize(_rhs.size()); 
    for(size_t i = 0; i < _data.size(); i++){ 
     _data[i] = _rhs[i]; 
    } 
    } 

}; 

/** @brief class for summation of vectors */ 

template <class A, class B> 
class ExprSum : public Expr <ExprSum<A,B> >{ 
private: 
    A _u; 
    B _v; 
public: 

    typedef vector3d::value_type value_type; 

    ExprSum(const Expr<A>& a, const Expr<B>& b): _u(a), _v(b) {} 

    value_type operator [] (size_t i) const { return (_u[i] + _v[i]); } 

    size_t size() const { return _u.size(); } 
}; 


/** @brief wrapper function of ExprSum class */ 
template <class A, class B> 
ExprSum <A,B> const operator + (Expr<A> const& u, Expr<B> const& v){ 
    return ExprSum <A,B> (u,v); 
} 


int main() 
{ 
    vector3d x,y; 

    x[0] = 1; 
    x[1] = 2; 
    x[2] = 3; 

    y[0] = 5; 
    y[1] = 4; 
    y[2] = 0; 

    // works fine 
    vector3d z; 
    z = x + y; 

    vector3d z_new = x + y ; // get error 

    return 0; 
} 

ответ

1

Это потому, что operator + вы определили производит Expr<ExprSum<A,B>>, который можно бросить только на ExprSum<A,B>. Конструктор vector3d ожидает const vector3d &.

Как operator = в пределах vector3d, вам необходимо определить аналогичный конструктор vector3d(const Expr<T> &).

+0

Отлично! Это разрешило ошибку ... Спасибо! – Pranav