Search code examples
c++functionimage-processingreturn-valuereturn-type

Wrap the return values with boolean type


I am trying to write a function with multiple return values. I need to handle the scenario when if there is no image in the path. How can i do this?

I have tried to use map. But it is more for Key, Value pairs is what I think(new to C++).

Below is my code:

tuple<Mat, Mat> imageProcessing(boost::filesystem::path pickPath){
    Mat img1, img2;
    // Check if file exists, if not return NULL
    if (!boost::filesystem::is_regular_file(pickPath)) {
        return make_tuple(NULL, NULL); 
    }

        imageFile = imread(pickPath.string());

        // Preprocess code (return 2 mat files)

        return make_tuple(img_1, img_2);
   }



int main(){
    path = "img.jpeg"
    tie(img1, img2) = imageProcessing(path);
}

Solution

  • Use std::vector if you want a contiguous collection of objects or use std::set if your function guarantees to return only unique results.

    Your method should also handle errors gracefully. In general there are two approaches in C++ for that:

    1. Exceptions. When your function encounters bad data/error codes from your 3rd party libraries or any other unexpected scenario you can throw an exception and the function caller needs to write code to handle it. Your method will probably look something like this:
    std::vector<Mat> ProcessImages(const boost:filesystem::path filePath)
    {
       if (!boost::filesystem::is_regular_file(pickPath)) {
           throw std::invalid_argument("file does not exist"!); //probably there's a better exception you could throw or you can define your own.
       }
    ...
    

    The caller would look like this:

      try{
            auto images = ProcessImage(myFilePath)
      }
      catch(const std::invalid_argument& e ) { 
         // write something to console, log the exception, terminate your process... choose your poison.
      }
    
    1. Return an error code. There are several ways of doing this - return a tuple with the first item being the error code and the second the vector, or pass the vector by reference and return only the error code:
    // if successful the function will return 0.
    enum ErrorCode
    {
      Successful = 0,
      InvalidArgs = 1,
      ...
    }
    
    ErrorCode ProcessImages(const boost:filesystem::path filePath, std::vector<Mat>& outImages)
    {
       if (!boost::filesystem::is_regular_file(pickPath)) {
       {
        return InvalidArgs;
       }
    
       imageFile = imread(pickPath.string());
    
       outImages.insert(img1);
       outImages.insert(img2);
    
       return Successful;
    }
    
    int main(){
        path = "img.jpeg"
        std::vector<Mat> images;
        auto result = ProcessImages(path, images);
        if (result != Successfull)
        {
          //error
        }
    }