Непонятный синтаксис, от vc ++ до c # - PullRequest
4 голосов
/ 11 октября 2011

У меня есть следующий код, который необходим для понимания класса, над которым я работаю, переводя с Visual C ++ на C #

typedef Rect<double, 2> Rect2;

Я просто не могу понять, что это значит. Я понял, что vc ++ использует 'stl' или 'std' и класс 'vector', который похож на c # list или arraylist, но синтаксис up полностью ускользает от меня.

Кстати, определение Rect написано так

template<class Real, int Dim>
class Rect {

Rect - это класс в одном из файлов проекта vc ++, но я не могу понять, в чем смысл этого определения типа. Это более 200 строк, поэтому вот начало объявления

template<class Real, int Dim>
class Rect {
public:

typedef Vector<Real, Dim> Vec;
typedef Rect<Real, Dim> Self;
typedef _RectPrivate::RectOp<Dim> RO;

Rect() : empty(true) {}
Rect(const Vec &vec) : empty(false), lo(vec), hi(vec) {}
Rect(const Vec &inLo, const Vec &inHi) : lo(inLo), hi(inHi) { markEmpty(); }
Rect(const Rect &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {}
template<class R> Rect(const Rect<R, Dim> &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {}

Любая помощь приветствуется.

Ответы [ 2 ]

7 голосов
/ 11 октября 2011

Исходя из ваших комментариев к другому ответу, проблема, с которой вы сталкиваетесь, заключается в том, что вы не понимаете, что такое шаблоны C ++. На самом деле они сильно отличаются от дженериков C #. Они концептуально схожи и синтаксически похожи, но их фактическая реализация сильно отличается.

Самый простой способ думать о шаблоне в C ++ - это механизм поиска и замены. Когда вы видите

typedef Rect<double, 2> Rect2;

Это означает, что нужно найти класс шаблона для Rect, который принимает два аргумента шаблона. Вот оно:

template<class Real, int Dim>
class Rect {

ОК, поэтому «double» соответствует «классу Real», а «2» соответствует «int Dim». Конечно же, double - это тип, а 2 - это int, поэтому он работает правильно. Теперь пройдитесь по классу шаблона и замените все экземпляры «Real» на «double» и «Dim» на 2. Результат:

typedef /* now we start replacing double for Real and 2 for Dim */ 
class Rect {
public:
typedef Vector<double, double> Vec;
typedef Rect<double, 2> Self;
typedef _RectPrivate::RectOp<2> RO;
Rect() : empty(true) {}
Rect(const Vec &vec) : empty(false), lo(vec), hi(vec) {}
...
} Rect2;

Обратите внимание, что результат поиска и замены в самом шаблоне определяет и использует больше шаблонов, которые сами должны быть найдены и заменены для их построения. Мы выполняем поиск и замену шаблона Vector и т. Д.

«typedef» просто означает «когда я говорю Rect2 я имею в виду Rect<double, 2>». Точно так же в C # вы можете сказать

using MyStringList = System.Collections.Generic.List<string>;

Существует много различий между шаблонами C # и шаблонами C ++. Очевидное отличие здесь состоит в том, что обобщенные значения C # могут быть параметризованы только с типами , но не с значениями , как это сделано в этом шаблоне. Другое отличие состоит в том, что шаблоны C ++ полностью создаются во время компиляции, и их нужно только юридически конструировать с фактическими аргументами, приведенными в программе. Принимая во внимание, что дженерики C # должны быть конструируемыми с любыми аргументами, которые отвечают заявленным ограничениям, и новое генерирование кода не происходит до времени выполнения.

4 голосов
/ 11 октября 2011

создает альтернативное имя для (псевдоним) Rect<double, 2>.Rect - это шаблон класса, который в некоторой степени сопоставим с Generics в C #.Так что Rect2 равно Rect с Real=double и Dim=2.

...