2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 С++ шаблоны и операторы
Сообщение04.01.2014, 00:07 
Вот чтот читаю и не могу понять эти две темы. Что же такое шаблоны и операторы. Как я понял, шаблоны это что-то вроде функций, но вот смысл заменять функцию методом, даже если использовать классы, я не понимаю... Я с тем же успехом могу и обычные функции использовать с объектами класса.
А вот операторы я, может быть, ещё понял, это что-то вроде аналогов стандартных действий типа "+" и т.п, но зачем они нужны?

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 00:12 
Аватара пользователя
Шаблоны, грубо говоря, это способ передавать тип как аргумент функции. Т.е., можно например написать универсальную функцию «max(a,b)», работающую на всём, что можно сравнивать (для чего определён operator<).
Вообще говоря — не нужны, в реальном проектировании не используют, так как к глупым запутываниям и ошибкам ведёт (если не считать какие-нибудь декораторы базовых типов).

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 00:53 
Аватара пользователя
BAHOO в сообщении #809334 писал(а):
Как я понял, шаблоны это что-то вроде функций, но вот смысл заменять функцию методом, даже если использовать классы, я не понимаю...
Шаблоны и функции - это так напрямую вещи не связанные. Шаблоны предназначены для того, чтобы писать какой-нибудь код, который умеет с разными типами делать в некотором смысле одно и то же. Например, чтобы не писать отдельные классы "список из целых чисел" и "список из символов", можно написать шаблон "список типа T" и использовать его (Есть такой шаблон в STL).

Urnwestek в сообщении #809339 писал(а):
Вообще говоря — не нужны, в реальном проектировании не используют, так как к глупым запутываниям и ошибкам ведёт (если не считать какие-нибудь декораторы базовых типов).
Ну, я могу сказать, что это неправда.

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 14:47 
ммм... всё равно как-то не особо понял разницу. Если вы говорите, что "Шаблоны предназначены для того, чтобы писать какой-нибудь код, который умеет с разными типами делать в некотором смысле одно и то же." т.е по сути та же самая функция, только работающая с разными типами данных, верно? т.е написав функцию, где происходит суммирование переменных типа int, то если использую эту функцию для переменных другого типа, то кампилятор выдаст ошибку или некорректно исполнит действие. А с шаблоном нормально всё будет работать. Верно?

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 14:57 
Ну, скажем так, можно написать шаблон, суммирующий как целые, так и действительные. Правда, с ублюдочной системой раздельной компиляции ++ это те ещё грабли.

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 15:04 
Аватара пользователя
BAHOO в сообщении #809440 писал(а):
т.е написав функцию, где происходит суммирование переменных типа int, то если использую эту функцию для переменных другого типа, то кампилятор выдаст ошибку или некорректно исполнит действие. А с шаблоном нормально всё будет работать. Верно?
Верно. Технически это происходит так: компилятор для каждого встречающегося в коде применения шаблона генерирует его специализацию. То есть, если написать
Код:
#include <cstdio>

template <typename T> T sum(T a, T b, T c)
{
  return a + b + c;
}

int main()
{
  int x = sum(1, 2, 3);
  long y = sum(1L, 2L, 3L);
  float z = sum(1., 2., 3.);
  printf("%d %ld %f\n", x, y, z);
}
То компилятор (при выключенной оптимизации) сгенерирует три отдельных функции sum<int>, sum<long> и sum<float>, и в каждом случае будет применена подходящая ему функция.

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 15:27 
ааа) теперь всё стало понятно. А что на счёт операторов? Просматривая про них информацию, я пришёл к предположению, что это аналогия обычных действий, только с объектами классов и т.п. Нашел такой пример
Код:
int a = 2;
int b = 2;
int c = a+b;

и его аналог с операторами
Код:
Circle a(2);
Circle b(2);
Circle c = a+b;
Circle c = a.operator+(b);

где Circle это такой класс. Значит оператор позволяет совершать действия с объектами класса чтоли? Но меня смущает это очень сильно. Сложно представить как можно сложить 2 объекта или сравнить их. Если я ничего не путаю, то если перегрузить конструктор, то можно сделать 2 объекта с разными параметрами. Да и ещё вопрос возник, если последние 2 строки кода одинаковы по смыслу, то зачем нужно загромаждение словом "operator". Просто если, например, сложить 5 переменных, то конструкция будет давольно длинной. Да ещё в с++ более крупная поддержка операторов и добавлена перегрузка операторов, значит я что-то не понимаю, не зря же столько мароки придумали

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 15:32 
Вообще-то параметрами шаблона могут быть не только типы, но и значения интегральных типов (логического типа bool, всех разновидностей символьных и целочисленных типов), члены перечислений и указатели (а также, на минуточку, другие шаблоны).
Urnwestek в сообщении #809339 писал(а):
Вообще говоря — не нужны, в реальном проектировании не используют, так как к глупым запутываниям и ошибкам ведёт (если не считать какие-нибудь декораторы базовых типов).
Приехали. К глупым ошибкам и запутываниям ведет как раз-таки дублирование кода, одинакового для разных типов. Другое дело, что шаблоны в C++ обладают довольно неудачным синтаксисом и рядом, скажем так, особенностей, из-за чего их лучше и вовсе не использовать в коде, если нет некоторого опыта работы с ними.
iifat в сообщении #809442 писал(а):
Ну, скажем так, можно написать шаблон, суммирующий как целые, так и действительные. Правда, с ублюдочной системой раздельной компиляции ++ это те ещё грабли.
В данном случае никаких грабель не будет, так как заранее известно множество возможных типов $\text{---}$ параметров шаблона (это очевидный пример на использование явного инстанцирования). Грабли начинаются, если таковое множество заранее неизвестно...

Операторы $\text{---}$ это просто синтаксический сахар, другой (более человекопонятный) способ записи определенных видов функций.

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 15:38 
Аватара пользователя
BAHOO в сообщении #809448 писал(а):
Да и ещё вопрос возник, если последние 2 строки кода одинаковы по смыслу, то зачем нужно загромаждение словом "operator". Просто если, например, сложить 5 переменных, то конструкция будет давольно длинной. Да ещё в с++ более крупная поддержка операторов и добавлена перегрузка операторов, значит я что-то не понимаю, не зря же столько мароки придумали

Все наоборот. Обычно классы складывать нельзя. Но иногда бывает удобно обозначить какую-нибудь операцию знаком +, чтобы не писать что-нибудь типа a.Add(b). Поэтому в C++ есть такая фича - можно определить метод или функцию operator+, и тогда выражение a + b автоматически будет преобразовываться в a.operator+(b) или operator+(a, b). То есть перегрузка операторов существует как раз для того, чтобы никогда не писать a.operator+(b).

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 16:34 
т.е, если я правильно вас понимаю, перегруженный оператор, это что-то вроде
Код:
int a=c+v+q;$
? я по примерам вот что нашёл
Код:
class Circle
{
private:
   double   r;
public:
   Circle(double R) { r = R; }

   Circle &operator+(Circle &C);
};

Circle &Circle::operator+(Circle &C)
{
   static Circle tmp(0);
   tmp.r = sqrt(r*r+C.r*C.r);
   return(tmp);
}


и вообще не понял смысла так сложно представлять код...

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 16:48 
Аватара пользователя
Код:
T& operator+ (...)
{
  static ... tmp;
  ...
  return tmp;
}
Никогда так не делайте.

Вот пример перегрузки сложения для класса, реализующего двумерные векторы:
Код:
class 2DVector
{
  double x;
  double y;
 
  2DVector& operator+=(const 2DVector & rhs)
  {
    x += rhs.x;
    y += rhs.y;

    return (*this);
  }
};

2DVector operator+(2DVector lhs, 2DVector rhs)
{
  lhs += rhs;
  return lhs;
}

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 16:56 
кажется понял в чём смысл, например я хочу сделать одно и тоже действие с несколькими переменными, то для того, чтобы не писать "+", я буду использовать такую конструкцию, чтоб просто через запятую перечислить данные с которыми будет выполняться действие. Верно?

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 17:47 
Аватара пользователя
Вот Вам пример, на тех же двухмерных векторах. До черты - определение класса и операторов, в main - как их использовать.

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <iostream>

class D2Vector
{
  private:
    double x;
    double y;

  public:
    double getX() const { return x; }
    double getY() const { return y; }

    D2Vector(double x_, double y_): x(x_), y(y_) {}
    //Default copy constructor is fine

    D2Vector& operator= (const D2Vector& rhs)
    {
      x = rhs.x;
      y = rhs.y;

      return *this;
    }
   
    D2Vector& operator+= (const D2Vector& rhs)
    {
      x += rhs.x;
      y += rhs.y;

      return *this;
    }
   
    D2Vector& operator-= (const D2Vector& rhs)
    {
      x -= rhs.x;
      y -= rhs.y;

      return *this;
    }

    D2Vector& operator*= (double rhs)
    {
      x *= rhs;
      y *= rhs;

      return *this;
    }

    D2Vector& operator/= (double rhs)
    {
      x /= rhs;
      y /= rhs;

      return *this;
    }

    friend double operator|(const D2Vector& lhs, const D2Vector& rhs); //scalar product
};

inline D2Vector operator+(D2Vector lhs, const D2Vector& rhs)
{
  lhs += rhs;
  return lhs;
}

inline D2Vector operator-(D2Vector lhs, const D2Vector& rhs)
{
  lhs -= rhs;
  return lhs;
}

inline D2Vector operator*(double lhs, D2Vector rhs)
{
  rhs *= lhs;
  return rhs;
}

inline D2Vector operator*(D2Vector lhs, double rhs)
{
  lhs *= rhs;
  return lhs;
}

inline D2Vector operator/(D2Vector lhs, double rhs)
{
  lhs /= rhs;
  return lhs;
}

inline double operator|(const D2Vector& lhs, const D2Vector& rhs)
{
  return lhs.x*rhs.x + lhs.y*rhs.y;
}

inline std::ostream& operator<< (std::ostream& out, const D2Vector& obj)
{
  out << "(" << obj.getX() << ", " << obj.getY() << ")";
  return out;
}

static const D2Vector i(1., 0.);
static const D2Vector j(0., 1.);

//----------------

using std::cout;
using std::endl;

int main()
{
  D2Vector x(1., 2.);
  D2Vector y = 2. * j;
  y += i;
  D2Vector z = 10. * x - 5. * y;
  D2Vector t = 5. * i - 3. * j;
  cout << x << endl;
  cout << y << endl;
  cout << z << endl;
  cout << t << endl;
  cout << x + y - z - t << endl;
  cout << (x + y) - (z + t) << endl;
  cout << (z | 2.*i + 3.*j) << endl;
}
 

 
 
 
 Re: С++ шаблоны и операторы
Сообщение04.01.2014, 17:59 
спс) теперь уже понятней стало=)

 
 
 
 Re: С++ шаблоны и операторы
Сообщение06.01.2014, 04:08 
Xaositect в сообщении #809464 писал(а):
Никогда так не делайте.

Почему же никогда? Так можно узнать сколько раз вызывали функцию. Да, в этом случае перегрузка оператора с возвратом статического объекта выглядит необдуманно и не очевидно.

 
 
 [ Сообщений: 16 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group