如何判断模版参数是不是指针?

zilaishuichina 2013-03-01 05:20:30
template <class T>
struct A
{
T m_Obj;
}

可以定义
A<B> a1;
也可以定义
A<C *> a2;

现在我想在模板中判断m_Obj的类型是一个对象类型,还是对象的指针
因为在模板中使用m_Obj时,
如果m_Obj是对象类型,那么应该是m_Obj.XXX
如果m_Obj是对象的指针类型,那么应该是m_Obj->XXX
...全文
1033 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
leolee82 2013-03-02
  • 打赏
  • 举报
回复
也可以参考7楼,针对指针和对象实现不同的成员函数,这样就没运行时判断了。 还可以尝试把objptr放入基类模板,再偏特化一个基类,可以实现不管T是否指针,都能保证基类成员都是指针。通过模板把参数传递给基类,就可以实现。ipad打字比较费劲,凑合看吧
leolee82 2013-03-02
  • 打赏
  • 举报
回复
也可以参考7楼,针对指针和对象实现不同的成员函数,这样就没运行时判断了。 还可以尝试把objptr放入基类模板,再偏特化一个基类,可以实现不管T是否指针,都能保证基类成员都是指针。通过模板把参数传递给基类,就可以实现。ipad打字比较费劲,凑合看吧
leolee82 2013-03-02
  • 打赏
  • 举报
回复
也可以参考7楼,针对指针和对象实现不同的成员函数,这样就没运行时判断了。 还可以尝试把objptr放入基类模板,再偏特化一个基类,可以实现不管T是否指针,都能保证基类成员都是指针。通过模板把参数传递给基类,就可以实现。ipad打字比较费劲,凑合看吧
zilaishuichina 2013-03-02
  • 打赏
  • 举报
回复
引用 7 楼 mingliang1212 的回复:
template<class T> T& getRef(T& o) { return o; } template<class T> T& getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时: getRef(m_Obj). xxx; 当然,解法还是很多的,……
template<class T> void DoXXX(T& o) { o.XXX; } template<class T> void DoXXX(T* o) { if(NULL != o) o->XXX; } 这样好一点
zilaishuichina 2013-03-02
  • 打赏
  • 举报
回复
引用 4 楼 supermegaboy 的回复:
引用 楼主 zilaishuichina 的回复:本帖最后由 zilaishuichina 于 2013-03-01 17:21:10 编辑 template <class T> struct A { T m_Obj; } 可以定义 A<B> a1; 也可以定义 A<C *> a2; 现在我想在模板中判断m_Ob……
我先试试
zilaishuichina 2013-03-02
  • 打赏
  • 举报
回复
引用 7 楼 mingliang1212 的回复:
template<class T> T& getRef(T& o) { return o; } template<class T> T& getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时: getRef(m_Obj). xxx; 当然,解法还是很多的,……
这样确实高端了~~~ 但是这里有一个问题 就是m_Obj是空指针的问题 如果m_Obj是指针类型的话 我希望编译出来的代码是 if (NULL != m_Obj) m_Obj->XXX;
condlover 2013-03-02
  • 打赏
  • 举报
回复
引用 2 楼 zilaishuichina 的回复:
引用 1 楼 ri_aje 的回复:特化. C/C++ code?12345template <class T>struct A <T*>{ T* m_Obj;}; 我不想特化呀 特化岂不是整个A的代码要再写一遍
麻烦楼主 能否 解释下 什么 叫特化
飞天御剑流 2013-03-02
  • 打赏
  • 举报
回复
寮曠敤 13 妤� taodm 鐨勫洖澶�:
一般来说,在自己的模板里同时支持这两者,都是一个设计滥用
这种顾虑有一定的道理,分开两个类的优点可以提高内聚性,降低复杂度,更容易维护,对解耦也有一定的帮助,缺点是如果类的数量较多,会造成类数目不必要地膨胀,上述优点会反过来变成缺点,因此需要酌情处理。
taodm 2013-03-02
  • 打赏
  • 举报
回复
一般来说,在自己的模板里同时支持这两者,都是一个设计滥用
乔巴好萌 2013-03-02
  • 打赏
  • 举报
回复
boost里有现成方法 http://www.boost.org/doc/libs/1_43_0/libs/type_traits/doc/html/boost_typetraits/reference/is_pointer.html
飞天御剑流 2013-03-02
  • 打赏
  • 举报
回复
一般而言,NULL指针检查就不应该用内嵌代码了,可用assert处理,getPtr也应改为inline。
iamnobody 2013-03-02
  • 打赏
  • 举报
回复
引用 18 楼 zilaishuichina 的回复:
引用 7 楼 mingliang1212 的回复:template<class T> T&amp; getRef(T&amp; o) { return o; } template<class T> T&amp; getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时:……
这样你就必须为每个xxx成员写一个模板...还是不如不用模板... 实际上,空指针是一个异常情况,应当在调用函数之前就确保非空了. 当然,你非要判断也是很简单的 . template<class T> T* getPtr(T& o) { return &o; } template<class T> T* getPtr(T* o) { return o; } if(getPtr(m_Obj) != 0)
iamnobody 2013-03-02
  • 打赏
  • 举报
回复
引用 9 楼 supermegaboy 的回复:
引用 7 楼 mingliang1212 的回复:template<class T> T&amp; getRef(T&amp; o) { return o; } template<class T> T&amp; getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时:……
暂时只想到这样,或类似的解法..呵呵..
飞天御剑流 2013-03-01
  • 打赏
  • 举报
回复
引用 7 楼 mingliang1212 的回复:
template<class T> T& getRef(T& o) { return o; } template<class T> T& getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时: getRef(m_Obj). xxx; 当然,解法还是很多的,……
解得好!看来我的思路未够开阔啊。如果你还有什么解法,请一并写出来。
  • 打赏
  • 举报
回复
tr1中 有
template<class Ty>
    struct is_pointer;
iamnobody 2013-03-01
  • 打赏
  • 举报
回复
template<class T> T& getRef(T& o) { return o; } template<class T> T& getRef(T* o) { return *o; } 用这个函数模板就可以. 当需要用到m_Obj时: getRef(m_Obj). xxx; 当然,解法还是很多的,
qq120848369 2013-03-01
  • 打赏
  • 举报
回复
偏特化...
飞天御剑流 2013-03-01
  • 打赏
  • 举报
回复
NND,有段代码写错了,如果使用if( Is_Pointer< T >::RESULT ),Is_Pointer应该这样写:

template< typename T >
struct Is_Pointer
{    
    enum { RESULT = false };
};

template< typename T >
struct Is_Pointer< T* >
{    
    enum { RESULT = true };
};
飞天御剑流 2013-03-01
  • 打赏
  • 举报
回复
引用 楼主 zilaishuichina 的回复:
本帖最后由 zilaishuichina 于 2013-03-01 17:21:10 编辑 template <class T> struct A { T m_Obj; } 可以定义 A<B> a1; 也可以定义 A<C *> a2; 现在我想在模板中判断m_Obj的类型是一个对象类型,还是对象的指针 因……
可以如下这样做:

struct TrueType {};
struct FalseType {};

template< typename T >
struct Is_Pointer
{
    typedef FalseType RESULT;
};

template< typename T >
struct Is_Pointer< T* >
{
    typedef TrueType RESULT;
};
于是,可以这样使用:

template <class T>
struct A
{
     T m_Obj;
     
     void fun( )
     {
         ........
         if( Is_Pointer< T >::RESULT ) ....m_Obj->xxx;
         else .......m_Obj.xxx;
         ........
     }
};
条件选择虽然可以工作,但使用了运行期代码,这得依赖于CPU的分支预测命中率了,注意到Is_Pointer< T >::RESULT是个元函数,那么可以把条件选择也移动到编译期,进行类型选择,可以改为如下这样:

template <class T>
struct A
{
     T m_Obj;
     
     void fun( )
     {
         .........
         .......GetSubObject( Is_Pointer< T >::RESULT );
         .......
     }

private :
    
    int GetSubObject( TrueType ){ return m_Obj->xxx; }
    int GetSubObject( FalseType ){ return m_Obj.xxx; }
};
这样编译后实体代码就直接剩下m_Obj->xxx或者m_Obj.xxx了。 如果觉得Is_Pointer< T >::RESULT还是不够优雅,在Is_Pointer内自定义到TrueType或者FalseType的inline转换函数,可以直接使用Is_Pointer< T >,就更简洁了。
ri_aje 2013-03-01
  • 打赏
  • 举报
回复
引用 2 楼 zilaishuichina 的回复:
引用 1 楼 ri_aje 的回复:特化. C/C++ code?12345template <class T>struct A <T*>{ T* m_Obj;}; 我不想特化呀 特化岂不是整个A的代码要再写一遍
那得看你具体干什么了,试一下 crtp.

template <typename T>
struct A<T*> : A<T>
{
};
加载更多回复(2)

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧