has_arrow_operator type trait 模板

hellwolf 2009-10-30 11:12:52
From: http://www.cnscn.org/htm_data/179/0805/14920.html


#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits.hpp>


/* type trait : has_arrow_operator<T> */
template <typename T>
struct has_arrow_operator {
template <int> struct test;

template<typename U>
static boost::type_traits::yes_type check_sig(test<sizeof(&U::operator ->)>* = NULL);

template<typename U>
static boost::type_traits::no_type check_sig(...);

static const bool value = sizeof(check_sig<T>(0)) == sizeof(boost::type_traits::yes_type);
};

/* operator -> available */
class A {
public:
A* operator -> ();
};

/* operator -> hidden */
class B {
protected:
B* operator -> ();
};

/* operator -> not available */
class C {
};

int main() {
std::cout << has_arrow_operator<int>::value << std::endl;
std::cout << has_arrow_operator<boost::shared_ptr<int> >::value << std::endl;
std::cout << has_arrow_operator<A>::value << std::endl;
// ????? how to make this false
//std::cout << has_arrow_operator<B>::value << std::endl;
std::cout << has_arrow_operator<C>::value << std::endl;
}


执行结果:
$ dync++ has_arrow_operator.cpp
0
1
1
0

不过对 B 使用的时候,编译器报错了, 怎么解决呢?

编译器: gcc (GCC) 4.4.1 20090725 (Red Hat 4.4.1-2)
...全文
175 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
hellwolf 2009-11-01
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 thy38 的回复:]
555555555555,我在VC2005里编译都通不过。
1>Compiling...
1>main.cpp
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>        .\main.cpp(38) : see reference to class template instantiation 'has_arrow_operator <T>' being compiled
1>        with
1>        [
1>            T=boost::shared_ptr <int>
1>        ]
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>        .\main.cpp(39) : see reference to class template instantiation 'has_arrow_operator <T>' being compiled
1>        with
1>        [
1>            T=A
1>        ]
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>Build log was saved at "file://d:\Projects\VC8\Console\Hello\Hello\Release\BuildLog.htm"
1>Hello - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

[/Quote]

我没 VC,不过你可以试试这个用 BOOST_TYPEOF 的版本

#include <boost/typeof/typeof.hpp>


/* type trait : has_arrow_operator<T> */
template <typename T>
struct has_arrow_operator {
template <typename> struct test;

template<typename U>
static boost::type_traits::yes_type check_sig(test<BOOST_TYPEOF(&U::operator ->)>* = NULL);

template<typename U>
static boost::type_traits::no_type check_sig(...);

static const bool value = sizeof(check_sig<T>(0)) == sizeof(boost::type_traits::yes_type);
};
thy38 2009-11-01
  • 打赏
  • 举报
回复
还是不行,哎,懒得再到Linux下搞了,Boost还没装呢。
kiwigiving 2009-10-31
  • 打赏
  • 举报
回复
顶贴了,楼主~
thy38 2009-10-31
  • 打赏
  • 举报
回复
555555555555,我在VC2005里编译都通不过。
1>Compiling...
1>main.cpp
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1> .\main.cpp(38) : see reference to class template instantiation 'has_arrow_operator<T>' being compiled
1> with
1> [
1> T=boost::shared_ptr<int>
1> ]
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1> .\main.cpp(39) : see reference to class template instantiation 'has_arrow_operator<T>' being compiled
1> with
1> [
1> T=A
1> ]
1>.\main.cpp(17) : error C2070: 'overloaded-function': illegal sizeof operand
1>Build log was saved at "file://d:\Projects\VC8\Console\Hello\Hello\Release\BuildLog.htm"
1>Hello - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
yshuise 2009-10-31
  • 打赏
  • 举报
回复
upup
hellwolf 2009-10-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jackyjkchen 的回复:]
引用 3 楼 hellwolf 的回复:
我是故意弄成 protected 的阿, 意图就是当其保护的时候 type trait 约定返回 false

但是很明显has_arrow_operator外部调用了B的->运算符,保护成员无法外部调用
[/Quote]

我的实现用了sizeof,其实只是强制让编译器产生一个类型展开,如果有其他办法产生同样的效果而且避免 private/protected 问题,那就是我感兴趣的解。
hellwolf 2009-10-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cphj 的回复:]
那应该用模板特化,大概是这样,你改着试试,我手头没装boostC/C++ codetemplate<B>// class B的定义放前面struct has_arrow_operator {
template<int>struct test;

template<B>static boost::type_traits::yes_type check_sig(test<sizeof(&U::operator->)>*= NULL);

template<B>static boost::type_traits::no_type check_sig(...);staticconstbool value=sizeof(check_sig<B>(0))==sizeof(boost::type_traits::no_type);
};
[/Quote]

谢谢,不过如果每个类都要偏特化就没必要用type trait了,type trait 目的就是要在不知道 T 是什么的情况下得到一些特征信息。 我查看了 boost 1.40 的 has_new_operator, 有人告诉我也有这样的问题,不能用于 private/protected 的 operator new。 这样的话这个 type trait 本身就不完备了。

cphj 2009-10-30
  • 打赏
  • 举报
回复
我改的有问题,你自己试试,就是保留
template <typename T>
struct has_arrow_operator原有代码的基础上,再复制一份,然后把第2份has_arrow_operator中的typename T替换成B,其他不变
cphj 2009-10-30
  • 打赏
  • 举报
回复
更正,这两句反了,应该是

// class B的定义放前面
template <B>

cphj 2009-10-30
  • 打赏
  • 举报
回复
那应该用模板特化,大概是这样,你改着试试,我手头没装boost
template <B>
// class B的定义放前面

struct has_arrow_operator {
template <int> struct test;

template<B>
static boost::type_traits::yes_type check_sig(test<sizeof(&U::operator ->)>* = NULL);

template<B>
static boost::type_traits::no_type check_sig(...);

static const bool value = sizeof(check_sig<B>(0)) == sizeof(boost::type_traits::no_type);
};
jackyjkchen 2009-10-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hellwolf 的回复:]
我是故意弄成 protected 的阿, 意图就是当其保护的时候 type trait 约定返回 false
[/Quote]
但是很明显has_arrow_operator外部调用了B的->运算符,保护成员无法外部调用
cphj 2009-10-30
  • 打赏
  • 举报
回复
外界无法访问protected成员

如果非要编译通过,把has_arrow_operator申明为class B的友元咯
hellwolf 2009-10-30
  • 打赏
  • 举报
回复
我是故意弄成 protected 的阿, 意图就是当其保护的时候 type trait 约定返回 false
mstlq 2009-10-30
  • 打赏
  • 举报
回复
class B {
protected:
B* operator -> ();
};
jackyjkchen 2009-10-30
  • 打赏
  • 举报
回复
B是保护成员啊,无法外部调用的,只能内部和子类调用

64,637

社区成员

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

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