为什么主流的静态类型语言不支持按返回类型重载函数/方法?我想不出有什么能做到。这似乎并不比支持按参数类型重载更有用或更合理。为什么它不那么受欢迎呢?
当前回答
如前所述,对仅因返回类型不同而不同的函数的模糊调用会引入模糊。 模糊性会导致有缺陷的代码。 必须避免有缺陷的代码。
试图模糊化所带来的复杂性表明这不是一个好的hack。 除了智力练习之外,为什么不使用带有引用参数的过程呢?
procedure(reference string){};
procedure(reference int){};
string blah;
procedure(blah)
其他回答
如前所述,对仅因返回类型不同而不同的函数的模糊调用会引入模糊。 模糊性会导致有缺陷的代码。 必须避免有缺陷的代码。
试图模糊化所带来的复杂性表明这不是一个好的hack。 除了智力练习之外,为什么不使用带有引用参数的过程呢?
procedure(reference string){};
procedure(reference int){};
string blah;
procedure(blah)
大多数静态语言现在也支持泛型,这将解决您的问题。如前所述,如果没有参数差异,就无法知道调用哪一个。如果你想这样做,使用泛型就可以了。
好的答案!A.Rex的回答尤其详细且有启发性。正如他所指出的,c++在编译lhs = func()时确实会考虑用户提供的类型转换操作符;(func实际上是结构体的名称)。我的解决方法有点不同——不是更好,只是不同(尽管它基于相同的基本思想)。
而我想写的是……
template <typename T> inline T func() { abort(); return T(); }
template <> inline int func()
{ <<special code for int>> }
template <> inline double func()
{ <<special code for double>> }
.. etc, then ..
int x = func(); // ambiguous!
int x = func<int>(); // *also* ambiguous!? you're just being difficult, g++!
我最终得到了一个使用参数化结构体(T =返回类型)的解决方案:
template <typename T>
struct func
{
operator T()
{ abort(); return T(); }
};
// explicit specializations for supported types
// (any code that includes this header can add more!)
template <> inline
func<int>::operator int()
{ <<special code for int>> }
template <> inline
func<double>::operator double()
{ <<special code for double>> }
.. etc, then ..
int x = func<int>(); // this is OK!
double d = func<double>(); // also OK :)
这种解决方案的一个好处是,任何包含这些模板定义的代码都可以为更多类型添加更多专门化。此外,您还可以根据需要对结构进行部分特殊化。例如,如果你想对指针类型进行特殊处理:
template <typename T>
struct func<T*>
{
operator T*()
{ <<special handling for T*>> }
};
作为一个负数,你不能写int x = func();用我的解决方案。你必须写int x = func<int>();。您必须显式地说明返回类型是什么,而不是让编译器通过查看类型转换操作符来确定它。我想说的是,“我的”解决方案和a . rex的解决方案都属于解决这个c++困境的帕累托最优方法:)
根据返回元素是标量还是数组,Octave允许不同的结果。
x = min ([1, 3, 0, 2, 0])
⇒ x = 0
[x, ix] = min ([1, 3, 0, 2, 0])
⇒ x = 0
ix = 3 (item index)
Cf也是奇异值分解。
如果函数被返回类型重载并且有这两个重载
int func();
string func();
在看到这样的调用时,编译器无法确定调用这两个函数中的哪一个
void main()
{
func();
}
由于这个原因,语言设计者通常不允许返回值重载。
然而,有些语言(如MSIL)允许按返回类型重载。当然,它们也面临上述困难,但它们有变通办法,为此您必须查阅它们的文档。