Skip to content

Expected

DryPerspective edited this page Nov 17, 2023 · 5 revisions

A C++98 version of C++23's std::expected. An expected<T,E> either contains an expected value of type T or an error value of type E. An expected value can be created as normal, and an unexpected value can be marked as so through the helper type dp::unexpected<E>.

Note that due to the lack of CTAD in C++98, the type of unexpected must be explicitly stated, e.g. dp::unexpected<error_t>(myError) rather than simply dp::unexpected(myError). We provide an alternative to this. Using function dp::unex will return a proxy type which is cheap to copy and which can be used to implicitly construct instances of dp::unexpected as well as dp::expected in its error state. This type should not be used explicitly by the programmer and exists for easier syntax.

The interface of dp::expected is as follows

Functions

operator*
operator->
Access contained expected value, without checks
operator bool
has_value
Checks if the object holds an expected value
value Access contained expected value, with checks
error Access contained unexpected value
value_or Returns contained expected value if held, or the parameter if not
swap Swaps the status and contained objects of two expected objects
operator== Compares contained expected values
dp::unex Allows deduction to create an unexpected value

Note that operator bool is not explicit, as this was not supported in C++98

Sample code

#include "cpp98/expected.h"

enum error_code{
    not_in_database,
    is_null
};

dp::expected<std::string, error_code> get_DB_field(){
    db_query.add("SELECT * FROM TABLE");
    db_query.open();
    if(db_query.empty()) return dp::unexpected<error_code>(not_in_database);  //Return unexpected error
    else if(db_query.get_field(foo) == NULL) return dp::unex(is_null);        //Return easy-syntax error value

    else return db_query.get_field(foo);
}

int main(){
    dp::expected<std::string,error_code> db_field = get_DB_field();
 
    if(!db_field.has_value()) print_error(db_field.error());
    else{
        do_things_to_process(*db_field);
    }
}
   

Clone this wiki locally