указатель this в макросе и функции - PullRequest
1 голос
/ 21 июня 2010

У меня есть код, который использует указатель «this» класса, который вызывает этот код. Например:

Some::staticFunction<templateType>(bind(FuncPointer, this, _1));

Вот я вызываю функцию bind из boost. Но это не важно. Теперь я должен обернуть этот код. Я сделал макрос:

#define DO(Type, Func) Some::staticFunction<Type>(bind(FuncPointer, this, _1));

И компилятор вставляет этот код в класс, который вызывает этот макрос, поэтому 'this' берет у вызывающего. Но я не хочу использовать макрос и предпочитаю функцию (встроенную). Но как решить это "прохождение". Могу ли я использовать его во встроенной функции, как в макросе, или я должен передать его вручную?

Ответы [ 2 ]

5 голосов
/ 21 июня 2010

Ключевое слово this можно поставить с помощью вызываемой вами функции

class MyClass {
  // ...
  template<typename Type, typename Func>
  void doit(Func f) {
    Some::staticFunction<Type>(bind(f, this, _1));
  }
};

После чего вы можете вызвать

doit<templateType>(FuncPointer);

Если хотите, вы можете наследовать функцию

// T must be a derived class of MyRegister<T>
template<typename T>
class MyRegister {
protected:
  template<typename Type, typename Func>
  void doit(Func f) {
    Some::staticFunction<Type>(bind(f, (T*)this, _1));
  }
};

class MyClass : MyRegister<MyClass> {
  // ...
};

Таким образом, вы можете просто использовать doit, а не писать сначала, как в макросе.Полезно, если у вас есть широкий диапазон классов, в которых вы используете функцию.

Редактировать: Обратите внимание, что приведение в стиле C * обязательно здесь (не можетиспользуйте static_cast), из-за частного наследования.Это безопасное приведение, если T получено из MyRegister<T>


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

DO(std::pair<A, B>, g);

Это попытается передать 3 аргумента макросу вместо 2. Вы можете изменить порядок типов и функций и использоватьпеременные макросы (которые являются функцией C ++ 0x, но доступны в некоторых компиляторах в режиме C ++ 03) или вы можете использовать typedef и передать псевдоним.

3 голосов
/ 21 июня 2010

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

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

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

...