2009-09-17 2 views
1

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

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

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

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

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 
}; 

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

+1

Я уверен, что есть способ сделать это, используя указатели функций и используя некоторое связующее для случая функции-члена. Но сначала я задал вопрос дизайну. Почему, по-вашему, вам нужно написать один и тот же код как в статических, так и в нестационарных идентификационных функциях-членах? Как часто, «как я могу решить эту проблему?» возможно, было лучше, чем «Я застрял на этом пути, чтобы решить мою проблему, как мне дальше?» – sbi

+0

Я хочу использовать тот же код, потому что я хочу просто использовать один центральный макрос вместо одного для статического и один для нестатических контекстов. Возможно, дизайн неправильный, но по крайней мере я сам не вижу лучшего. –

ответ

0

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

+0

быстрый тест выглядит хорошо, спасибо. –

0

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

Изменение вашей функции() и элемента _id на статичность выставляет их как для ваших статических функций-членов, так и в качестве бонуса, уменьшает использование вашей памяти.

+0

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

+0

И в этом случае, какой статический метод и почему он должен иметь одно и то же тело? В противном случае вы могли бы: a) передать макрос (или функцию) идентификатора, что печатать (this-> which() или :: which()), или вы могли бы реализовать статику как: {using :: which; идент(); } – UncleBens

+0

моей целью является использование одной коллекции в основном «автоматических» макросов трассировки/журнала, а не каких-либо конкретных в зависимости от контекста. они также должны, насколько это возможно, автоматически регистрировать, к какому основному экземпляру они принадлежат. {using :: which(); ...} будет противоречить цели простоты и автоматизации, а также передавать явные сообщения. назовите меня ленивым, но я не хочу думать о том, в каком контексте я есть, если я смогу каким-то образом автоматизировать это. –

1

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

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

Извините, но я не вижу, где это позволит мне вызывать, который() в одном центральном макросе без другого кода для статических/нестатических контекстов. –

+0

К сожалению, я не заметил вашего требования для макроса без аргументов для идентификации экземпляра. Мое решение требует, чтобы вы передали экземпляр в качестве аргумента. –

Смежные вопросы