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)
...全文
218 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是保护成员啊,无法外部调用的,只能内部和子类调用
内容概要:本文研究了基于Q-Learning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,旨在提升其在复杂海洋环境下的控制性能。通过建立AUV的动力学模型,将Q-Learning算法与传统PID控制相结合,实现控制器参数的在线自适应优化,有效增强了系统的响应速度、稳定性和抗干扰能力。研究采用Matlab进行仿真验证,结果表明该方法在轨迹跟踪与姿态控制方面具有优越表现,为水下机器人智能控制提供了可行的技术路径与理论支持。; 适合人群:具备自动控制理论、强化学习或水下机器人建模背景,从事相关科研工作的研究人员、高校研究生及工程技术开发者。; 使用场景及目标:①应用于高精度、强鲁棒性的水下机器人运动控制系统设计;②开展智能PID控制器在非线性、时变系统中的参数自整定研究;③作为强化学习在复杂工业控制场景中落地的典型案例参考,推动算法与工程实践融合。; 阅读建议:建议结合提供的Matlab代码进行仿真实验,重点剖析Q-Learning与PID融合的架构设计、奖励函数设定及参数收敛过程,可进一步拓展至与其他智能优化算法(如DQN、Actor-Critic)的对比研究,深化对自适应控制机制的理解。
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 Matlab 被视为一种功能卓越的编程平台,特别是在数值运算和数据分析方面展现出广泛的应用价值。在应对多元非线性回归的挑战时,Matlab 拥备多种工具和函数,支持用户对复杂的数据进行构建模型和适配。本指南将重点阐释在 Matlab 环境下如何执行多元非线性回归分析。 我们需要掌握三种关键的回归指令: 1. `polyfit(x,y,n)`:此函数适用于拟合一元幂函数,能够导出一个多项式模型。例如,若知晓数据呈现二次函数形态,可选择`n=2`来适配一个二次曲线。 2. `regress(y,x)`:这是一个多元线性回归指令,能够处理多个自变量对因变量的影响。即便数据并非完全呈现线性特征,该函数也能提供一个线性近似。 3. `nlinfit(x,y,’fun’,beta0)`:这是最为通用的非线性回归指令,适用于适配任何类型的函数,无论是一元或多元,前提是用户能够定义函数形式(`fun`参数)。 回归分析的核心在于寻找一组最优的系数,使得模型能够最恰当地描述数据。这通常涉及选择一个合适的函数形态,随后通过最小化误差平方和来估算系数。在Matlab中,`regress`指令主要用于处理线性模型,而`nlinfit`则处理更为复杂的非线性模型。 对于多元线性回归模型,我们可以用如下形式进行表述: \[ y = \beta_0 + \beta_1x_1 + \beta_2x_2 + \cdots + \beta_px_p + \epsilon \] 其中,\( y \)是因变量,\( x_1, x_2, \ldots, x_p \)是自变量,\( \beta_0, \beta_1, ...

65,211

社区成员

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

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