List function max element treating empty container in c++

131 views Asked by At

How do I treat situation if the list is empty? I want the program to print "Not possible to find max on an empty list" but the value must be returned...

template<typename T>
T max(const std::list<T>&l){
  
  std::list <T> l1=l;

  auto largest=l1.begin();

   for(auto it=begin(l1);it!=end(l1);++it){
     
     ++largest;
   
    if((*it)>(*largest)){
    
      largest=it;

     }
   }
   
   return *largest;
  }

I tried adding

template<typename T>
T max(const std::list<T>&l){
  if(l.empty()){

    std::cout<<"List is empty! "<<std::endl;
  }

  else{
  std::list <T> l1=l; 

  auto largest=l1.begin();

   for(auto it=begin(l1);it!=end(l1);++it){
     
     ++largest;
   
    if((*it)>(*largest)){
    
      largest=it;

     }
   }
   
   return *largest;
  }
}

In the main.ccp file, the input of element type double is requested, so if, for example, we enter 'b', program should print "List is empty! " and should only put entered doubles into container

1

There are 1 answers

0
eerorika On BEST ANSWER

A conventional way to solve this is to not return a copy of the element, but to instead return an iterator to the element. In the case of an empty range, you can return iterator to the end of the range. This is how std::max_element and std::ranges::max_element of the standard library handle the case.

Another way is to wrap the return type in std::optional, and to return std::nullopt when the input range is empty.

Another way is to treat the case of empty input range as an error on part of the caller. There are many ways to handle error cases in C++:

  • One way that can be correct, but is generally less safe, is to simply not handle the error case in the function at all. Document that calling the function with an empty range results in undefined behaviour (which is what happens in case of both of your attempts). In this case, you must handle the case by checking the range before, and then not calling the function if the range is empty. This is how std::ranges::max of the standard library handles (or rather, how it doesn't handle) the case.
  • Another way is to throw an exception.
  • Another way is to wrap the return type in a monadic error wrapper such as std::expected that is proposed for C++23.

Note that as I mention above as examples, the standard library already provides function templates for the purpose of finding the maximum element, so writing the described function is rather unnecessary.