谁能实现all_cast!

JoeRen 2003-10-21 09:16:33
众所周知,老式的强制类型转换有很多缺点。为此C++提供了一套新的类型转换关键字:reinterpret_cast/static_cast/const_cast。
由于它们的用法类似于函数模板,因此,自行提供模板函数以提供自定义的转换是可行的。boost中的lexical_cast/numeric_cast等就是很好的例子。
现在的问题是,它们并不能取代原来的老式强制。例如在泛型编程中
template<typename A,typename B>
A myfunc(B data)
{
return reinterpret_cast<A>(data);
}
不一定能通过编译。问题是如果B到A有一个隐式的转换,那么至少在VC上就会报错:从类型B到A存在隐式转换,请改用其他表达方法。
从实用的观点看,最好是有个通用的类型转换方法,能够跟老式的转换完全兼容。也就是说,老式转换能处理的它都能处理,并且结果一样。这个函数模板,姑且称为all_cast吧。
当然,all_cast有个最简单的实现方法:

template<typename A, typename B>
A all_cast(B data)
{
return (A)data;
}

但如果将来C++取消了老式强制呢?……当然这在近期不会发生。
不管怎样,探讨一下完全不用老式强制如何实现老式强制的所有功能也是有意义的。
大家不妨探讨一下?
...全文
52 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
短歌如风 2003-10-29
  • 打赏
  • 举报
回复
楼上的代码并不是type-cast,逻辑完全不同。
你试一试
char * p1("abcdefg");
void * p2(NULL);
p2 = lexical_cast<void*, char*>()(p1);
carmark 2003-10-29
  • 打赏
  • 举报
回复
template < class type1, class type2 >
class lexical_cast {
public:
type1 operator() ( type2 value )
{
type1 result;
std::stringstream s;
s << value ;
s >> result;
return result;
}
}
Wolf0403 2003-10-28
  • 打赏
  • 举报
回复
任意逻辑的转换是不可能也不应该由一段代码处理的,B如何转换为A应该是由B或者A定义的,定义的方法就是操作符重载或是构造函数。

极度赞同ing,而且我在上面也提到了,呵呵。向伟大的版中央靠拢
短歌如风 2003-10-27
  • 打赏
  • 举报
回复
...A myfunc(B data)...
则A一定要有可使用的拷贝构造。
如果B可以转换为A,则:
1:A有参数为(const)B(&)的构造函数,则这个构造函数被调用
2:B定义了operator A(),则这个操作符和A的拷贝构造函数被调用
3:B可隐式转换为C,而A有参数为(const)C(&)的构造函数,则这个构造函数被调用
我现在只想到了这3种情况,其它情况大家再想想。
Wolf0403 2003-10-27
  • 打赏
  • 举报
回复
为什么如果B可以转换为A,那么A一定可以用B构造
短歌如风 2003-10-27
  • 打赏
  • 举报
回复
问题是这些转换用“老式转换”能不能完成?
任意逻辑的转换是不可能也不应该由一段代码处理的,B如何转换为A应该是由B或者A定义的,定义的方法就是操作符重载或是构造函数。
Wolf0403 2003-10-27
  • 打赏
  • 举报
回复
呵呵,转换的基本明白了。但是除了老大说的三种情况,未免不会出现一个
A cast(const B& b)
{
return reinterrupt<A&>(b);
}
这样的变态代码。算是第四种^_^

而且如果单纯是 ... A myfunc (B data); 情况就更多了:
B 是一个结构,A 是 B 的一个成员,而且没有提供接受 A 的 B::ctor
B 是一个字符串,A 是生成结果,类似 Factory Pattern。。。
短歌如风 2003-10-24
  • 打赏
  • 举报
回复
错误……是A(data)
短歌如风 2003-10-24
  • 打赏
  • 举报
回复
如果B可以转换为A,那么A一定可以用B构造,应该可以这样:
return A(B);
ttlb 2003-10-22
  • 打赏
  • 举报
回复
回复人: JoeRen(地球发动机) ( ) 信誉:100 2003-10-21 14:43:00 得分:0


还有一条不兼容的地方。
如果有下列定义

class A
{
public:
operator B();
};

class B
{
private:
friend class A;
B(const B&);
};

那么,老式转换
A a;
B b=(B)a;
是有效的。此时调用a.operator B()将a转换成B。
但前述解决方案不可行。因为B的复制构造函数是私有的。


老式转换真行吗?真的不用调用拷贝构造函数?
Lymtics 2003-10-22
  • 打赏
  • 举报
回复
我也觉得在C++的范围中讨论这个问题意义不大..
毕竟同楼上说的一样:
"C++本来就讲究实用,何必为了完美而在一些细节上钻牛角尖。"----------------好句子啊~~~

但如果我遇到这种问题,我也许把问题转移到别的地方解决...
比如:项目中所有的类派生于同一个基类(祖先).做一个库.提供某个函数,在运行时刻根据vtbl动态在两个对象传送函数指针.(当然,你要让程序崩溃也是可以的)..也就是说或牺牲一些效率或牺牲一些安全性来做到完美.......不过自我觉得不值.
Analyst 2003-10-22
  • 打赏
  • 举报
回复
出于兼容性考虑,老式的转换是不可能被取消的。怎么方便就怎么用,在这个问题没必要拘泥。我记得Alexandrescu写了篇文章探讨min/max的C++实现,谈论了半天发现还是用宏定义的min/max最简单好用。C++本来就讲究实用,何必为了完美而在一些细节上钻牛角尖。
oyd 2003-10-21
  • 打赏
  • 举报
回复
很难,顶先!
不过至少BS本人就不会同意这么做,因为他老人家一向认为强制转换一般来说是设计低劣的表现。
Wolf0403 2003-10-21
  • 打赏
  • 举报
回复
首先呢,对于基本类型之间的转换,应该用的是 static_cast 而不是 reinterpret_cast。
其次,C++ 的核心思想之一:用类表示概念。类的设计者应当提供合适的转换函数,而不是需要一个通用的 all_cast。鉴于各种类的复杂性,all_cast 几乎是不可能的,也是没有意义的
Wolf0403 2003-10-21
  • 打赏
  • 举报
回复
呵呵,披着 GP 的 C
Muf 2003-10-21
  • 打赏
  • 举报
回复
template<typename A, typename B>
inline A& all_cast(B& data)
{
return (A)data;
}
JoeRen 2003-10-21
  • 打赏
  • 举报
回复
还有一条不兼容的地方。
如果有下列定义

class A
{
public:
operator B();
};

class B
{
private:
friend class A;
B(const B&);
};

那么,老式转换
A a;
B b=(B)a;
是有效的。此时调用a.operator B()将a转换成B。
但前述解决方案不可行。因为B的复制构造函数是私有的。
JoeRen 2003-10-21
  • 打赏
  • 举报
回复
上面第一条应该是
好多老式强制不能做的它都能做
JoeRen 2003-10-21
  • 打赏
  • 举报
回复
楼上这位够厉害的。可惜这不是我的本意。
这个实现跟老式强制并不兼容。因为:
1、好多老式强制能做的它不能做。
2、对于复杂的继承情况,它不能保证跟老式强制得出相同的结果(例如,有多重继承的情况)。
更重要的是,这个东西实在是——太!危!险!了!
因此,这是个不正确的答案。
oyd 2003-10-21
  • 打赏
  • 举报
回复
这种算吗?
没有任何的类型检查,连C风格的强制转换都可以阻止你把一个string转化为一个list。
那么这种强制转换纯粹就是破坏c++的类型系统,有什么必要呢。
加载更多回复(1)

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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