简体   繁体   中英

How to write function to help distinguish empty values versus 0?

I am trying to calculate the average based on input from a vector. How can I distinguish to the caller of my function that an empty vector was provided versus a vector with just 0 values? Can I do both in one function or do I need 2 functions?

You could return a std::optional<T> to signal that the your function may not return an actual value in the case of an empty vector.

std::optional<double> avg(const std::vector<int>& n) {
    if(n.size() < 1)
        return std::nullopt;
    return std::accumulate(n.begin(), n.end(),0) / static_cast<float>(n.size());
}


int main() {

    std::vector<int> numbers;
    auto average = avg(numbers);
    if(average) {
        std::cout << "the average is" << average.value() << std::endl;
    }else {
        std::cout << "Could not compute average!" << std::endl;

    }
}

You can use templates to do what you want as follows :


#include <iostream>
#include <vector>
using namespace std;
template<typename T>
T average(const std::vector<T> &vec)
{
    if(vec.empty())
    {
        //you can also assert instead of throw
        throw std::runtime_error("Vector passed is empty");//throw if the vector is empty because we don't want to operate on an empty vector
    }
    T sum{};
    for(T elem: vec)
    {
        sum += elem;
    }
    return sum/vec.size();
}
int main()
{
   std::vector<float> myvec1{1,2,3.4};
   std::cout<<"average is: "<<average(myvec1);
   
   std::vector<int> myvec2;
   average(myvec2);//this will (terminate)print "vector passed is empty"

    return 0;
}

An empty vector has no average, it is undefined, just like 0/0 is undefined. It is the caller's responsibility not to calculate 0/0, and it is the caller's responsibility not to calculate an empty vector average.

There is no good way to deal nicely with undefined calculations such as 0/0 or empty vector average in C++. The usual approach is to let the users sort it out. The caller should check the length of the vector before trying to call your function. Otherwise the callee would need to check the length, return a special value, and then the caller would need to check that the returned value is special. This is unneeded complexity. If the user needs to check every call, let them check every call before making it, not after. Just add an assert to help debugging.

Alternative approaches would be to return a NaN or to throw an exception. This allows the users to validate calculation results with whatever granularity they want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM