为什么主流的静态类型语言不支持按返回类型重载函数/方法?我想不出有什么能做到。这似乎并不比支持按参数类型重载更有用或更合理。为什么它不那么受欢迎呢?
当前回答
根据返回元素是标量还是数组,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也是奇异值分解。
其他回答
这一点在c++中略有不同;我不知道它是否会被认为直接通过返回类型重载。它更像是一种模板专门化,以。
util.h
#ifndef UTIL_H
#define UTIL_H
#include <string>
#include <sstream>
#include <algorithm>
class util {
public:
static int convertToInt( const std::string& str );
static unsigned convertToUnsigned( const std::string& str );
static float convertToFloat( const std::string& str );
static double convertToDouble( const std::string& str );
private:
util();
util( const util& c );
util& operator=( const util& c );
template<typename T>
static bool stringToValue( const std::string& str, T* pVal, unsigned numValues );
template<typename T>
static T getValue( const std::string& str, std::size_t& remainder );
};
#include "util.inl"
#endif UTIL_H
util.inl
template<typename T>
static bool util::stringToValue( const std::string& str, T* pValue, unsigned numValues ) {
int numCommas = std::count(str.begin(), str.end(), ',');
if (numCommas != numValues - 1) {
return false;
}
std::size_t remainder;
pValue[0] = getValue<T>(str, remainder);
if (numValues == 1) {
if (str.size() != remainder) {
return false;
}
}
else {
std::size_t offset = remainder;
if (str.at(offset) != ',') {
return false;
}
unsigned lastIdx = numValues - 1;
for (unsigned u = 1; u < numValues; ++u) {
pValue[u] = getValue<T>(str.substr(++offset), remainder);
offset += remainder;
if ((u < lastIdx && str.at(offset) != ',') ||
(u == lastIdx && offset != str.size()))
{
return false;
}
}
}
return true;
}
util.cpp
#include "util.h"
template<>
int util::getValue( const std::string& str, std::size_t& remainder ) {
return std::stoi( str, &remainder );
}
template<>
unsigned util::getValue( const std::string& str, std::size_t& remainder ) {
return std::stoul( str, &remainder );
}
template<>
float util::getValue( const std::string& str, std::size_t& remainder ) {
return std::stof( str, &remainder );
}
template<>
double util::getValue( const std::string& str, std::size_t& remainder ) {
return std::stod( str, &remainder );
}
int util::convertToInt( const std::string& str ) {
int i = 0;
if ( !stringToValue( str, &i, 1 ) ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to int";
throw strStream.str();
}
return i;
}
unsigned util::convertToUnsigned( const std::string& str ) {
unsigned u = 0;
if ( !stringToValue( str, &u, 1 ) ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to unsigned";
throw strStream.str();
}
return u;
}
float util::convertToFloat(const std::string& str) {
float f = 0;
if (!stringToValue(str, &f, 1)) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to float";
throw strStream.str();
}
return f;
}
double util::convertToDouble(const std::string& str) {
float d = 0;
if (!stringToValue(str, &d, 1)) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to double";
throw strStream.str();
}
return d;
}
这个例子并没有精确地使用根据返回类型的函数重载解析,但是这个c++非对象类使用模板专门化来通过私有静态方法模拟根据返回类型的函数重载解析。
每个convertToType函数都调用函数模板stringToValue(),如果你看一下这个函数模板的实现细节或算法,它调用getValue<T>(param, param),它返回一个类型T并将其存储到T*中,T*作为其参数之一传递到stringToValue()函数模板。
除了这样的东西;c++并没有通过返回类型来实现函数重载解析的机制。可能还有我不知道的其他构造或机制可以通过返回类型模拟解析。
大多数静态语言现在也支持泛型,这将解决您的问题。如前所述,如果没有参数差异,就无法知道调用哪一个。如果你想这样做,使用泛型就可以了。
如果函数被返回类型重载并且有这两个重载
int func();
string func();
在看到这样的调用时,编译器无法确定调用这两个函数中的哪一个
void main()
{
func();
}
由于这个原因,语言设计者通常不允许返回值重载。
然而,有些语言(如MSIL)允许按返回类型重载。当然,它们也面临上述困难,但它们有变通办法,为此您必须查阅它们的文档。
如前所述,对仅因返回类型不同而不同的函数的模糊调用会引入模糊。 模糊性会导致有缺陷的代码。 必须避免有缺陷的代码。
试图模糊化所带来的复杂性表明这不是一个好的hack。 除了智力练习之外,为什么不使用带有引用参数的过程呢?
procedure(reference string){};
procedure(reference int){};
string blah;
procedure(blah)
我认为这是现代c++定义中的一个GAP……为什么?
int func();
double func();
// example 1. → defined
int i = func();
// example 2. → defined
double d = func();
// example 3. → NOT defined. error
void main()
{
func();
}
为什么c++编译器不能抛出例子“3”和错误 接受例子“1+2”中的代码??