概述
2004-07-05 13:25:31 别逗了
问个问题:
1。C++中为什么不允许通过返回类型重载函数?
2。为什么不允许通过返回类型解析模板函数?
2004-07-05 14:47:55 完美废人
返回类型是一种可有可无的东西……
2004-07-05 16:41:23 完美废人
瞧见什么叫高手了吧
2004-07-05 18:32:46 别逗了
那operator type()怎么说?不是根据返回值判断调用那个函数的吗?
2004-07-05 18:34:49 完美废人
void f();
int f();
f(); //which one to go?
2004-07-05 18:35:18 别逗了
增加一条规则就是了。
2004-07-05 18:35:27 无锋之刃
啊哈!
2004-07-05 18:35:31 完美废人
怎么描述?
2004-07-05 18:35:53 完美废人
type-cast operators are individual functions, not the same one with diff return type
2004-07-05 18:39:11 别逗了
void f();
int f();
之间只是存在歧义,当出现歧义的时候,按照C++的习惯,制定一个最佳匹配规则。规则不行的时候,扩展语法, 调用形式: f() void;或者f() int;
2004-07-05 18:39:37 完美废人
手工确认调用哪个函数?那还要重载干吗?
2004-07-05 18:39:44 完美废人
而且
2004-07-05 18:39:57 无锋之刃
最佳匹配规则上说你这两个选择一样地好……
2004-07-05 18:39:58 完美废人
void f() 和 int f();,没有重载规则可以达到调用 void f();
2004-07-05 18:40:13 别逗了
那问题是,可以判别的时候,就不用指定了啊.
2004-07-05 18:40:32 无锋之刃
那问题是,没有办法 判别。
2004-07-05 18:40:39 完美废人
为了这么一点方便?我不如直接写 void f_void(); 和 int f_int(); 算了
2004-07-05 18:41:03 别逗了
那你放到模板里面怎么办?
2004-07-05 18:41:27 完美废人
拜托了大哥,尽量简化问题是每个程序员应尽的义务
2004-07-05 18:41:43 别逗了
调用形式作一个扩展不行?例如f() void;
2004-07-05 18:41:57 完美废人
f() void; 和 f(); 怎么区别?
2004-07-05 18:42:06 别逗了
指定返回值是void的f().
2004-07-05 18:42:15 完美废人
我直接 f(); 就会有二义性错误
2004-07-05 18:42:21 别逗了
对.
2004-07-05 18:42:23 完美废人
这样的语法,还不如不用重载
2004-07-05 18:42:43 无锋之刃
这是历史的倒退。
2004-07-05 18:42:52 别逗了
问题是,加了这个,对你以前的重载有影象吗?
2004-07-05 18:43:11 别逗了
你以前的代码规则照样起作用.
2004-07-05 18:43:57 别逗了
你完全可以不通过返回值重载函数---只有需要的人才会用到这个功能.
2004-07-05 18:44:11 别逗了
为什么就倒退了?
2004-07-05 18:44:25 完美废人
struct base
{
virtual void f();
};
struct d:public base
{
void f();
int f();
};
base * p = new d;
p->f(); ??
2004-07-05 18:44:45 无锋之刃
编译器无法通过返回类型来判断应该调用哪个函数。链接器也是。
2004-07-05 18:45:20 别逗了
首先,你按照新的规则,定义了一对重载函数,却指望按照老的方式调用,当然不行.
2004-07-05 18:45:49 完美废人
如果没有 struct d,我的老规则完全适用
2004-07-05 18:45:51 无锋之刃
那什么是新的调用方式?
2004-07-05 18:45:52 别逗了
我的意思,增加了新的规则,你的老的重载方式,还是像以前一样工作.
2004-07-05 18:46:02 完美废人
除非你规定,所有的 void f(); 都必须改成 f() void; 这样调用
2004-07-05 18:46:07 别逗了
p->f() void;
或者
2004-07-05 18:46:12 别逗了
p->f() int;
2004-07-05 18:46:26 完美废人
struct S
{
void f(); //how to call?
};
2004-07-05 18:46:30 无锋之刃
那我还不如写p->f_int()呢。搞那么复杂。
2004-07-05 18:46:41 完美废人
这个重载完全没有意义
2004-07-05 18:47:07 别逗了
好,我举个有意义的例子给你.
2004-07-05 18:48:20 完美废人
plz
2004-07-05 18:48:27 别逗了
max(T1& lhs, T2& rhs)
{
//应该返回什么类型?
}
int i = max(2, 3.3);
double d = max(2, 3.3);
2004-07-05 18:48:51 别逗了
这是内部类型,可以互相转换,如果是自定义类型呢?
2004-07-05 18:49:05 别逗了
max应该返回什么类型?
2004-07-05 18:49:08 完美废人
自定义类型怎么能进行比较?
2004-07-05 18:49:17 完美废人
如果能比较,就应该能转化
2004-07-05 18:49:27 别逗了
我的自定义类型定了了less不可以阿?
2004-07-05 18:49:39 完美废人
你试试看。
2004-07-05 18:51:17 别逗了
例如我定义了dec类型和money类型。返回值需要做转换,转换可能丢失精度。如果不需要转换,那就没有这个问题。
2004-07-05 18:52:41 完美废人
所以你有
dec max(const dec &, const money &);
和
money max(const dec &, const money &): ?
2004-07-05 18:54:00 完美废人
1、建议你看看 C++0x 的 typeof
2、不论什么时候,重载决断是编译器的,不存在动态联编,所以根据返回值重载不切实际。
2004-07-05 18:54:21 别逗了
对。我的money类型是定点数,在进行数学运算的时候,有时候需要转换成dec类型,以防止中间运算过程的精度误差。算完了,还要转换回来。
2004-07-05 18:54:30 完美废人
2、不论什么时候,重载决断是编译器的,不存在动态联编,所以根据返回值重载不切实际。
2004-07-05 18:55:03 别逗了
呵呵,我要的就是决断是编译器的。
2004-07-05 18:55:07 完美废人
这个地方,你不如用 enum 好了。
2004-07-05 18:55:13 完美废人
抱歉,我是说 union
2004-07-05 18:55:28 别逗了
union和我的问题有啥关系?
2004-07-05 18:55:56 完美废人
typedef union {dec, money} rt_t;
rt_t max (const money &, const dec &);
2004-07-05 18:56:36 别逗了
靠,这不行的,这可真的运行期判决了。
2004-07-05 18:56:37 完美废人
对 money 和 dec 设计用 NullObject 作为默认值,可以用来检查 rt_t 的值
2004-07-05 18:56:50 完美废人
你不靠运行期决断,返回值就不存在意义。
2004-07-05 18:57:21 完美废人
money m;
dec d;
infile >> m >> d;
max(m, d); ??
2004-07-05 18:57:34 别逗了
谁说得?先确定一下,你不反对我要返回不同类型的数据了吧?
2004-07-05 18:57:44 完美废人
反对。
2004-07-05 18:57:56 完美废人
强烈反对用 union 这么变态的东西
2004-07-05 18:58:02 别逗了
好,那一个个问题来。
2004-07-05 18:58:10 benbear
强烈反对废人此观点
2004-07-05 18:58:21 别逗了
首先,我才不要返回union 。
2004-07-05 18:58:21 完美废人
我有一个很好的解决办法
2004-07-05 18:58:31 完美废人
想不想听?
2004-07-05 18:58:38 别逗了
我要返回的就是money或者是dec
2004-07-05 18:58:56 完美废人
std::pair 作为返回好了,哈哈。
2004-07-05 18:59:43 benbear
你试过
dec max(const dec &, const money &);
和
money max(const dec &, const money &):
能通过编译吗?
2004-07-05 18:59:47 别逗了
一样没用。你怎么知道返回值是什么类型?返回两个?那你怎么知道该用那个?
2004-07-05 19:00:06 完美废人
把不是返回值的一个指针作为 0
2004-07-05 19:00:17 完美废人
这是为什么我用指针而不是引用的原因
2004-07-05 19:00:22 完美废人
指针有 NullObject
2004-07-05 19:00:26 别逗了
我知道不能,所以我才不满意C++强加的限制。
2004-07-05 19:01:01 别逗了
越来越垃圾的设计了。[shake]
2004-07-05 19:01:12 完美废人
总比越来越垃圾的语言好[:D]
2004-07-05 19:01:28 完美废人
荼毒你一个,幸福俺大家
2004-07-05 19:01:32 别逗了
怎么垃圾了,我说得新特性你可以不用啊。
2004-07-05 19:01:46 完美废人
那么你告诉我,怎么调用 basd::virtual void f(); ??
2004-07-05 19:02:22 完美废人
我真的可以对一个
void func (base * p)
{
p->func(); //不是 p->func() void; ?
}
2004-07-05 19:02:47 完美废人
没有什么东西是没有代价的。
2004-07-05 19:03:21 别逗了
你不是不用嘛,干吗要通过返回值重载?只要你不仅仅通过返回值重载(这是现状),就不必知道新特性。但是,你需要仅仅通过返回值重载,你就需要新特性。
2004-07-05 19:03:41 完美废人
我当然不用!但是我不能保证从我的类派生的家伙们不用!
2004-07-05 19:04:07 完美废人
作为一个接口基类,我必须把一切该死的可能性都考虑进去
2004-07-05 19:04:35 别逗了
OK.那么,、先确认一点:新特性对既有的代码,不需要修改,同意不?
2004-07-05 19:04:52 完美废人
不同意
2004-07-05 19:05:03 别逗了
那你举例反对。
2004-07-05 19:05:45 完美废人
struct Base
{
virtual void fun();
};
void f(const Base * p)
{
p->fun(); //你要我抄多少遍?
}
2004-07-05 19:07:29 别逗了
很显然,这是调用void fun()啊。现有规则就能解决。如果派生类定义了同名的,而类型不同,那就是同名覆盖,而不是重载。
2004-07-05 19:08:11 完美废人
好,某个 newbie 写了
struct Derived : public Base
{
virtual void fun();
virtual int fun();
};
如何??
2004-07-05 19:08:31 别逗了
这个在现有规则下合法吗?
2004-07-05 19:09:00 完美废人
我的基类是旧规则的,但是这个 newbie 是学习新规则长大的,如何?旧的代码已经不能通用了!
2004-07-05 19:09:48 别逗了
靠,newbie写的是新代码!他既没有遵守旧规则,也没有遵守新规则!
2004-07-05 19:10:09 完美废人
他为什么没有遵守新规则?很漂亮的 rt-overload
2004-07-05 19:10:32 别逗了
让我想想。
2004-07-05 19:11:57 完美废人
:)恭候。
2004-07-05 19:14:17 别逗了
OK。这里只能调用void fun(),因为,virtual void fun();
virtual int fun();是两个函数。而Base当中根本就不认识virtual int fun();所以,你老的代码f(const Base * p)
只有一种选择,就是原来的那一个。
2004-07-05 19:14:47 别逗了
所以,这里没有任何问题。[:D]
2004-07-05 19:15:05 无锋之刃
[?]
2004-07-05 19:15:15 完美废人
呵呵,有道理。
2004-07-05 19:15:28 完美废人
刀子,替我砍!
2004-07-05 19:15:45 无锋之刃
你去弄个砧板来
2004-07-05 19:15:48 别逗了
好啊,继续,我接着。
2004-07-05 19:16:34 完美废人
那么,如果 struct Base 放在新规则下,我就必须写 p->fun() void; 了?
2004-07-05 19:18:12 别逗了
不必。只有在老规则不能分辨的时候才需要这样写。
例如:
long f(int);
char f(char);
不需要写成f(10) int;
2004-07-05 19:19:10 完美废人
struct Base
{ virtual void fun(); };
struct Derived : public Base
{ virtual int fun(); };
算是隐藏?
2004-07-05 19:19:30 完美废人
这个在现有模式下是怎么处理的?
2004-07-05 19:19:33 别逗了
但是也有部分地方会有问题,就是没有一个是匹配的,但是存在两个同样优先级的转换时。
2004-07-05 19:19:50 完美废人
这个从来都存在问题……无奈了
2004-07-05 19:20:03 完美废人
我上次写那个 bi_map,都差点放弃重载了
2004-07-05 19:20:37 别逗了
1。现有模式不能只通过返回值区分重载。2。如果你的参数不同,那么,这两个函数覆盖。
2004-07-05 19:21:23 完美废人
都是 (void) 的时候,发生的是覆盖、修改接口、还是??
2004-07-05 19:21:34 别逗了
覆盖。
2004-07-05 19:21:44 别逗了
错了。
2004-07-05 19:21:50 完美废人
到底是……?
2004-07-05 19:21:52 别逗了
怎么都是void?
2004-07-05 19:22:11 完美废人
int f(void); 和 派生类的 void f(void); 或者相反。
2004-07-05 19:22:21 无锋之刃
你们在讨论虾米……
2004-07-05 19:22:22 别逗了
是这样:
覆盖
2004-07-05 19:22:42 完美废人
这个东西我是没法明白了……刀子或者鸡丁还有希望:(
2004-07-05 19:22:52 别逗了
倒!
2004-07-05 19:23:01 无锋之刃
《EC》上说“绝对不要重新定义继承而来的非虚函数”……
2004-07-05 19:23:17 别逗了
是啊。
2004-07-05 19:23:23 完美废人
struct Base
{ virtual void fun(); };
struct Derived : public Base
{ virtual int fun(); };
2004-07-05 19:23:26 无锋之刃
那……
2004-07-05 19:23:30 完美废人
struct Base
{ virtual void fun(); };
struct Derived : public Base
{ virtual int fun(); };
2004-07-05 19:23:30 别逗了
但是,语言则要考虑到。
2004-07-05 19:23:34 完美废人
两个函数签名相同啊,怎么会是覆盖的?
2004-07-05 19:24:00 无锋之刃
返回值类型是不会被Name-mangling机制处理的。
2004-07-05 19:24:18 完美废人
所以应是一般的派生类重写而已
2004-07-05 19:24:23 别逗了
晕倒,签名规则不可以变啊?况且,签名规则根本就是和编译没太大关系得,连接系统关系比较大而以。
2004-07-05 19:24:38 完美废人
我现在是说传统 C++……
2004-07-05 19:24:45 无锋之刃
你把你的想法提交C++ Standard Commitee,也许有可能……
2004-07-05 19:24:46 完美废人
不了解过去就无法预测将来
2004-07-05 19:26:06 别逗了
我好像在那里看到过说为什么不能通过返回值重载的,但是,我实在是想不起来任何线索了。
2004-07-05 19:26:24 完美废人
别逗了:这两个函数签名相同,不可能是覆盖……
2004-07-05 19:26:49 无锋之刃
也不可能是重载,因为参数列表一样。
2004-07-05 19:27:05 完美废人
本来就不可能,因为是在不同的 class scope
2004-07-05 19:27:14 完美废人
所以只能是重写了。
2004-07-05 19:27:32 无锋之刃
重定义。
2004-07-05 19:27:33 别逗了
函数签名不包括返回值?那dump出来的dll中怎么解析我的返回值类型的?
2004-07-05 19:27:59 完美废人
dump 出来的 dll 还支持 const char * 到函数的映射呢……
2004-07-05 19:29:41 别逗了
不要搞,我问你:int CppUnit::CompilerOutputter::wrapColumn(void)
Name-mangling之后怎么知道返回值是int而不是void的?
2004-07-05 19:29:52 完美废人
不知道。
2004-07-05 19:30:09 完美废人
返回值和 name mangling 无关
2004-07-05 19:31:09 别逗了
int CppUnit::CompilerOutputter::wrapColumn(void)
是我用depends从dll中导出的函数名。
这是C函数名:
?wrapColumn@CompilerOutputter@CppUnit@@QBEHXZ
你是这里面没有返回值信息?
2004-07-05 19:31:29 完美废人
我没看到 int 啊
2004-07-05 19:31:44 别逗了
那时你不知道怎么解码。
2004-07-05 19:32:11 完美废人
呵呵:)这是一句没有说服力的反驳
2004-07-05 19:32:11 无锋之刃
在C中调用C++的函数,要在C++代码中使用extern "C"来禁止重载的……
2004-07-05 19:33:05 别逗了
晕倒,我刚才的两个名字就是同一个,只不过depends能够?wrapColumn@CompilerOutputter@CppUnit@@QBEHXZ解码成int CppUnit::CompilerOutputter::wrapColumn(void)这样可以读的格式。
2004-07-05 19:33:26 无锋之刃
那也只是凑巧……
2004-07-05 19:33:36 完美废人
呵呵~这是用结论逆推理论。
2004-07-05 19:33:58 别逗了
什么凑巧,C++的dll全都是这样的,自己可用depends去看。
2004-07-05 19:34:30 无锋之刃
别在Dll中使用太多重载,不然会死得很惨的。
2004-07-05 19:34:34 别逗了
我的意思是:Name-mangling不过是一种实作手段而以。
2004-07-05 19:34:48 完美废人
我没有 depends。逆试试
struct { int f();}
struct { void f();}
有没有区别
2004-07-05 19:35:07 无锋之刃
但是为什么编译器厂商都没有把你想的实作出来呢?
2004-07-05 19:35:23 别逗了
你不是用vc的吗?怎么没有depends?
2004-07-05 19:35:29 完美废人
不知道:(
2004-07-05 19:35:52 别逗了
depends.exe没有?晕倒!
2004-07-05 19:36:11 完美废人
好像没装 vc-tools 的说……
2004-07-05 19:36:13 无锋之刃
C++编译出的Dll在Console下怎么调用?
2004-07-05 19:36:24 完美废人
LoadLibrary
2004-07-05 19:36:30 别逗了
可以得。
2004-07-05 19:36:33 无锋之刃
又一个API……
2004-07-05 19:36:40 无锋之刃
[:8]
2004-07-05 19:36:55 别逗了
C编译出的dll难道不需要?
2004-07-05 19:37:07 完美废人
我正在看 CreateRemoteThread,居然被别逗了老兄拉来侃这个……
2004-07-05 19:37:28 别逗了
玩那个干吗?
2004-07-05 19:37:41 完美废人
为了他*妈*的造福人民,调试病毒用。
2004-07-05 19:38:01 无锋之刃
传说中尝遍百草的废人……
...
最后
以上就是舒服小土豆为你收集整理的C++中为什么不允许通过返回类型重载函数的辩论的全部内容,希望文章能够帮你解决C++中为什么不允许通过返回类型重载函数的辩论所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复