存储或反映变量的“参考级别”

时间:2011-06-04 17:15:03

标签: c++ variables

C ++中是否有办法反映变量的“指针级别数”(例如,int* a为1级,int** b为2级,{{1是0级)

..除了使用int c并解析出来的字符串?

我问的原因是我正在使用pointers to member functions,我需要知道是否在编译时调用成员函数typeidobj->func()

7 个答案:

答案 0 :(得分:4)

如果objT**,则obj.*foo的格式不正确。所以你只需要弄清楚它是指针还是非指针。你可以使用重载。

template<typename T, typename M> void f(T *obj, M m) { // pointer
  (obj->*m)();
}

template<typename T, typename M> void f(T &obj, M m) { // not a pointer
  (obj.*m)();
}

这样做的缺点是它只适用于零参数成员函数指针,并且它不会返回这些函数返回的值(如果有的话)。您不能执行以下操作(可以轻松实现),因为两个分支都将进行类型检查

if(is_pointer(obj)) v = (obj->*m)(arg...); else v = (obj.*m)(args...);

所做的只是调用一个函数来取消引用你的对象,如果它是一个指针

template<typename T> T &deref(T *t) { return *t; }
template<typename T> T &deref(T &t) { return t; }

然后你可以说

v = (deref(obj).*m)(args...);

答案 1 :(得分:3)

部分模板专业化将很容易告诉你:

template<typename T>
struct PtrLevel
{
    enum { value = 0 };
};

template<typename TTarget>
struct PtrLevel<TTarget*>
{
    enum { value = PtrLevel<TTarget>::value + 1 };
};

示范:http://ideone.com/ZPH8X

在C ++ 0x中,您可以使用decltype和SFINAE来处理智能指针,使其报告为具有非零指针级别。

答案 2 :(得分:3)

您可以使用TR1中std::is_pointer标头中的type_traits(使用部分特化来产生答案),但使用重载解析可能更简单。

这是一个例子,假设返回void,没有参数,并且不需要处理多个间接层:

template <typename T, typename F>
inline void invoke(T& obj, F func)
{
    (obj.*func)();
}

template <typename T, typename F>
inline void invoke(T* obj, F func)
{
    (obj->*func)();
}

如果您需要处理多个间接级别,可以用以下代码替换第二个函数:

template <typename T, typename F>
inline void invoke(T* obj, F func)
{
    invoke(*obj, func);
}

这将以递归方式剥离间接级别,直到您最终得到可以调用成员函数的内容。

答案 3 :(得分:2)

拯救的一些模板魔法:

template<typename T>
struct Depth { enum DepthEnum { value = 0 };};

template<typename T>
struct Depth<T*> { enum DepthEnum{ value = Depth<T>::value +1 };};

template<typename T>
size_t getDepth(T const& o)
{
    return Depth<T>::value;
}

int main()
{
    int         a0;
    int*        a1;
    int**       a2;
    int***      a3;
    int****     a4;
    int*****    a5;
    int******   a6;
    std::cout << getDepth(a0) << std::endl;
    std::cout << getDepth(a1) << std::endl;
    std::cout << getDepth(a2) << std::endl;
    std::cout << getDepth(a3) << std::endl;
    std::cout << getDepth(a4) << std::endl;
    std::cout << getDepth(a5) << std::endl;
    std::cout << getDepth(a6) << std::endl;
}

输出:

> g++ test.cpp
> ./a.out
0
1
2
3
4
5
6

回到你想要它的原因。这似乎有点怀疑。您的编译器已经知道在编译时起诉的版本。记住C ++对它的输入非常严格,这个信息在编译时是已知的,因此如果你使用了错误的版本,你将会遇到编译器错误。

答案 4 :(得分:0)

我不知道有任何内置方法可以做到这一点,但你可以实现一个模拟“计数指针”的小模板类,你可以很容易地确定你的“指针深度”:

template <typename T> class Ptr {
  private:
    T* ptr;
    int d;
  public:
    // overload all meaningful operators, like * etc.
    // e.g.
    T& operator*() {
      return *T;
    }
    int depth() const {
      return d;
    }
}

答案 5 :(得分:0)

只要您的指针有效,您就可以使用以下代码:它将为您传递给它的对象提供参考级别(只需稍加更改即可更改它以返回对象指针引用,只需使用注释而不是acual代码并直接使用countPartial):

template <class T> int countPartial(T *x,int depth)
//use template <class T> T& countPartial(T *x)
{
    return countPartial(*x,depth+1);
    //return countPartial(*x);
}

template <class T> int countPartial(T &x,int depth)
//use template <class T> T& countPartial(T &x)
{
    return depth;
    //return x;
}

template <class T> int count(T x)

{
    return countPartial(x,0);
}

答案 6 :(得分:-1)

可能这个糟糕的解决你的麻烦 T是模板。 funcptr ptr功能。

int callfunc( T ptr)
{

depth = 0;

if ( typeof(ptr)!=  typeof(funcptr))

{


depth++;
depth = depth + callfunc(*ptr);
}
return depth;
}