Различать статические и нестатические методы в C ++ во время компиляции? - PullRequest
1 голос
/ 17 сентября 2009

Для некоторой автоматизации трассировки для идентификации экземпляров я хочу позвонить либо:

  • нестатический метод содержащего объекта, возвращающий его идентификатор
  • что-то еще, что всегда возвращает тот же идентификатор

Мое текущее решение - иметь базовый класс с методом which () и глобальной функцией which (), которая должна использоваться, если не в контексте объекта. Это, однако, не работает для статических функций-членов, здесь компилятор предпочитает нестатический метод по сравнению с глобальным.

Упрощенный пример:

class IdentBase
{
public:
  Ident(const std::string& id) _id(id) {}
  const std::string& which() const { return _id; }
private:
  const std::string _id;
};

const std::string& which() { static const std::string s("bar"); return s; }

#define ident() std::cout << which() << std::endl

class Identifiable : public IdentBase
{
public:
  Identifiable() : Ident("foo") {}
  void works() { ident(); }
  static void doesnt_work() { ident(); } // problem here
};

Можно ли как-то избежать использования обходных путей, таких как специальный макрос, для статических функций-членов (возможно, с использованием некоторой магии шаблона)?

Ответы [ 3 ]

1 голос
/ 17 сентября 2009

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

template<typename T>
const std::string& which(const T& object)
{ static const std::string s("bar"); return s; }

Специализируйте шаблон функции для определенного класса.

class IdentBase
{
public:
    IdentBase(const std::string& id): _id(id) {}
    const std::string& id() const { return _id; }
private:
    const std::string _id;
};

template<>
const std::string& which(const IdentBase& object)
{ return object.id(); }

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

int main()
{
    int i;
    std::cout << which(i) << std::endl;

    IdentBase foo("foo");
    std::cout << which(foo) << std::endl;

    return 0;
}
0 голосов
/ 17 сентября 2009

Возможно, вы сможете использовать is_member_function_pointer из библиотеки Boost TypeTraits. Предложение sbi об использовании другого кода в статических и нестатических случаях, вероятно, лучше.

0 голосов
/ 17 сентября 2009

Вам нужен отдельный идентификатор для каждого экземпляра каждого класса, как в вашем примере, или вы просто пытаетесь определить, какой класс находится в трассировке?

Изменение функции which () и члена _id на static приведет к тому, что они будут доступны как функциям статического члена, так и в качестве бонуса уменьшат использование памяти.

...