2010-09-15 2 views
0

У меня есть маленький кусочек кода из библиотеки, которая делает это:Странный #define в шаблоне?

#define VMMLIB_ALIGN(var) var 

template< size_t M, typename T = float > 
class vector 
{ 

... 

private: 
// storage 
VMMLIB_ALIGN(T array[ M ]); 

}; 

И вы можете назвать это не делает

//(vector<float> myVector) 
myVector.array; 

Нет скобку или что-нибудь.

какой?


После прочтения ответов, похоже, я должен был больше посмотреть. XCode's «Перейти к определению» дал мне только один результат. Поиск в библиотеке дал мне другое:

#ifndef VMMLIB_CUSTOM_CONFIG 
# ifndef NDEBUG 
# define VMMLIB_SAFE_ACCESSORS 
# endif 
# define VMMLIB_THROW_EXCEPTIONS 
# ifdef VMMLIB_DONT_FORCE_ALIGNMENT 
# define VMMLIB_ALIGN(var) var 
# else 
# ifdef __GNUC__ 
#  define VMMLIB_ALIGN(var) var __attribute__((aligned(16))) 
# elif defined WIN32 
#  define VMMLIB_ALIGN(var) __declspec (align (16)) var 
# else 
#  error "Alignment macro undefined" 
# endif 
# endif 
#endif 

Это предлагает различные настройки, в зависимости от того, для какой системы она предназначена.

Независимо от того, спасибо. Не могу поверить, что я запутался в доступе к члену!

+1

Как объявляется myVecetor? Предполагая, что это экземпляр вашего шаблона класса, заявленное вами утверждение является законным, но не особенно полезным, и, конечно же, не является «вызовом» ни к чему. –

+0

ничего себе ... Я думаю, Objective-C действительно отравил мой разум. Я не узнал доступ к ivar ... Спасибо, ребята. –

+0

Я получил вниз за то, что был глупым !? Вау, спасибо. как будто '# define's и' templates' являются основами каждого языка программирования. –

ответ

4

В конечном итоге myVector.array ссылается на переменную массива в классе, а переменные не нуждаются в функциональной нотации ().

Идентификаторы BTW/all-capital должны использоваться только для макросов препроцессора (как они есть здесь). В этом случае макрос VMMLIB_ALIGN должен использоваться для облегчения более позднего «зачарования» кода, сгенерированного для и рядом с переменной array (например, с префиксом статического, внешнего, const, volatile или специфического для компилятора) и/или добавление некоторых связанных функций, таких как функции get/set/search/clear/serialise, которые работают с массивом.

В общем случае, когда вы не знаете, что делает макрос, вы можете получить больше информации, запустив компилятор с помощью командной строки, запрашивающего вывод препроцессора (в GNU g ++ коммутатор -E) ... то вы сможете увидеть фактический исходный код, с которым имеет дело компилятор C++.

EDIT - несколько мыслей повторно ваш комментарий, но слишком долго, чтобы включить в комментарии моего собственного ...

классы

C++ являются частными, пока другой спецификатор доступа не предусмотрено (но на практике общественный интерфейс нормально положите сначала, чтобы программист все же должен помнить, чтобы явным образом использовал private). structs по умолчанию являются общедоступными. Таким образом, данные фактически отображаются по умолчанию в наиболее распространенном стиле кодирования. И ему не нужна семантика функционального вызова для доступа к ней. Objective-C может быть лучше в этом ... ваш комментарий подразумевает, что вы используете функциональную нотацию вызовов для членов данных и функций, которые по умолчанию скрыты? Очень хорошо иметь общую нотацию! В C++, трудный случай, когда у вас есть что-то вроде ...

struct Point 
{ 
    double x, y; 
}; 

... 

// client usage: 
this_point.x += 3 - that_point.y; 

... то нужно изменить, чтобы ...

struct Point 
{ 
    double angle, distance; 
}; 

... Вы должны были бы некоторые довольно фантазии и подробные вручную и не очень эффективные прокси-объекты x и y, чтобы старый код клиента продолжал работать без изменений при вычислении x и y «на лету» и, при необходимости, обновляя угол и расстояние. Единая нотация замечательна - позволяет реализовать изменения без изменений в исходном коде клиента (хотя клиенты должны перекомпилировать).

+0

ok, я просто предположил, что основной массив вектора будет скрыт или что-то в этом роде. Бух ... Цель-С доходит до меня. –

+0

Чтобы ответить на ваши дополнительные комментарии, в Objective-C все члены являются частными и используют геттеры/сеттеры из-за управления памятью ref-count по умолчанию. '[object setMember: newValue];' или для get 'int myNum = [object member];' Я искал, какой синтаксис в C++ не требует '()', потому что я не получил доступ к публичный член навсегда! Кроме того, шаблоны мне сложно читать. –

1

array не метод, это массив типа T размера M.

3

Возможно, я излишне смотрю, но если вы посмотрите на макрос #define, он просто записывает переменную в класс.

Так у вас есть

class vector 
{ 
... 
    T array[ M ]; 
}; 

после расширения. Так что это просто переменная public на вашем классе.

+0

ничего себе. Я думал, что это будет частным ... но, я думаю, нет. –

1

Во-первых, для записи шаблоны не имеют никакого отношения к этому. Специального взаимодействия между макросом и фактом, что ваш класс является шаблоном.

Во-вторых, перейдя по имени макроса, я предполагаю, что он предназначен для обеспечения выравнивания переменной.

То есть, чтобы получить выровненный экземпляр x из типа X, вы бы использовать VMMLIB_ALIGN(X x);

На практике, макрос не делает ничего. Он просто вставляет свой аргумент, поэтому приведенные выше результаты имеют код X x; и ничего больше.

Однако может быть, что макрос определяется по-разному в зависимости от аппаратной платформы (поскольку требования к выравниванию могут различаться между платформами) или со временем (используйте эту макетную компоновку, как это было раньше, а затем замените ее «реальная» реализация)

Однако это кажется бессмысленным, поскольку компилятор уже обеспечивает естественное выравнивание для всех переменных.