2014-12-23 2 views
4

Я все еще новичок в C++ и пытаюсь понять шаблоны выражений. Я натолкнулся на пример кода на Wikipedia. Я Понял большую часть программы и как она работает, но я не ясно, каким образом эти строки интерпретируются компилятором:Нечеткий синтаксис C++ при перегрузке оператора

operator A&()    { return static_cast<  A&>(*this); } 
operator A const&() const { return static_cast<const A&>(*this); } 

от базового выражения шаблона класса ниже. Обычно синтаксис перегрузки оператора равен return_datatype operator+ (args){body} (например, для оператора +), но это дает ошибки, а функции в компиляции компиляции без какой-либо ошибки. Может ли кто-нибудь объяснить эти две строки? Что делает A& и A const& перед операциями? И почему A& operator()(){} и A const& operator()(){} не работает? Это дает ошибку:

no matching function for call to 'Vec::Vec(const Expr<Vec>&)' 
    ExprSum(const Expr<A>& a, const Expr<B>& b): _u(a), _v(b) {} 

-Pranav

Полный код:

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

using namespace std; 


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


class Vec : public Expr<Vec> { 
private: 
    container_type x; 
public: 
    Vec(){} 
    Vec(size_type length) :x(length) {} 
    size_type size() const { return x.size(); } 

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

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

}; 


template <class A, class B> 
class ExprSum : public Expr <ExprSum <A,B> >{ 
private: 
    A _u; 
    B _v; 
public: 
    typedef Vec::size_type size_type; 
    typedef Vec::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_type size() const { return _u.size(); } 
}; 


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(){ 

    size_t n = 10; 
    Vec x(n); 
    Vec y(n); 
    Vec z; 

    for(size_t i = 0; i < n; i++){ 
    x[i] = i; 
    y[i] = 2*i; 
    } 

    z = x + y; 

    cout << z[7] << endl; 

    cout << "Hello world!" << endl; 
    return 0; 
} 
+0

Они называются операторами преобразования или операторами трансляции. Они используются для предоставления семантики для преобразования различных типов. См. [Здесь] (http://en.cppreference.com/w/cpp/language/cast_operator) – dreamlax

+0

Вместо того, чтобы «не работать», объясните, в чем проблема: –

ответ

4

Это conversion operator. Он похож на обычный перегруженный оператор, но у него нет указанного типа возврата, а вместо символа оператора у вас есть целевой тип преобразования.

+0

Спасибо @Sebastian за указание на его преобразование оператор. Предоставленная связь действительно разъяснила мои сомнения. Спасибо, -Праван – Pranav

Смежные вопросы