在编译时区分c ++中的静态和非静态方法?

时间:2009-09-17 16:38:14

标签: c++ templates macros static-methods

对于某些跟踪自动化来识别我想要调用的实例:

  • 包含对象的非静态方法返回其标识符
  • 其他总是返回相同ID的内容

我目前的解决方案是拥有一个带有方法的基类,该方法使用()和一个全局函数(如果不在对象的上下文中则应该使用)。 然而,这对静态成员函数不起作用,这里编译器更喜欢非静态方法而不是全局方法。

简化示例:

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 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

在示例中,您是否需要为每个类的每个实例使用不同的标识符,或者您只是想确定跟踪中哪个类?

将which()函数和_id成员更改为static会将它们暴露给静态成员函数,并作为奖励减少内存使用量。

答案 2 :(得分:0)

您可以使用Boost TypeTraits库中的 is_member_function_pointer。 sbi建议在静态和非静态情况下使用不同的代码可能更好。