Function overloading by return type?

前端 未结 14 2260
终归单人心
终归单人心 2020-11-22 03:55

Why don\'t more mainstream statically typed languages support function/method overloading by return type? I can\'t think of any that do. It seems no less useful or reasona

14条回答
  •  死守一世寂寞
    2020-11-22 04:17

    This one is slightly different for C++; I don't know if it would be considered overloading by return type directly. It is more of a template specialization that acts in the manner of.

    util.h

    #ifndef UTIL_H
    #define UTIL_H
    
    #include 
    #include 
    #include 
    
    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
        static bool stringToValue( const std::string& str, T* pVal, unsigned numValues );
    
        template
        static T getValue( const std::string& str, std::size_t& remainder );
    };
    
    #include "util.inl"
    
    #endif UTIL_H
    

    util.inl

    template
    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(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(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;
    }
    

    This example is not exactly using function overload resolution by return type, however this c++ non object class is using template specialization to simulate function overload resolution by return type with a private static method.

    Each of the convertToType functions are calling the function template stringToValue() and if you look at the implementation details or algorithm of this function template it is calling getValue( param, param ) and it is returning back a type T and storing it into a T* that is passed into the stringToValue() function template as one of its parameters.

    Other than something like this; C++ does not really have a mechanism to have function overloading resolution by return type. There may be other constructs or mechanisms that I'm not aware of that could simulate resolution by return type.

提交回复
热议问题