CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Using c++17 optional<>

    c++17 has the optional<> class. It can either contain a value of the specified type or no value. For a function that returns values and has to indicate whether an issue has occurred (throwing an exception not warranted), we are looking into having these functions always return a type optional<> so that if a value is present it is ok and if no value is present an error has occurred.

    Consider

    Code:
    #include <optional>
    #include <string>
    #include <cctype>
    #include <iostream>
    #include <tuple>
    using namespace std;
    
    auto getDigit(const string& str)
    {
    	using digits = tuple<int, int, int>;
    
    	if (str.size() == 3) {
    		for (const auto s : str)
    			if (!isdigit(s))
    				return optional<digits> {};
    
    		return make_optional(digits {str[0] - '0', str[1] - '0', str[2] - '0'});
    	}
    
    	return optional<digits> {};
    }
    
    int main()
    {
    	string s;
    
    	cout << "Enter 3 digits: ";
    	cin >> s;
    
    	if (auto d = getDigit(s); d.has_value()) {
    		auto [d1, d2, d3] = *d;
    
    		cout << "Digit 1 is " << d1 << "\ndigit 2 is " << d2 << "\ndigit 3 is " << d3 << endl;
    	} else
    		cout << "Invalid input" << endl;
    }
    NOTE that getDigit() is for test only!

    Does any guru have any comments re returning success/failure and values in this way.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  2. #2
    Join Date
    Feb 2017
    Posts
    677

    Re: Using c++17 optional<>

    Quote Originally Posted by 2kaud View Post
    Does any guru have any comments re returning success/failure and values in this way.
    I know optional has been available in Boost for some time and here's a note on its intended usage,

    http://www.boost.org/doc/libs/1_66_0..._optional.html
    Last edited by wolle; February 7th, 2018 at 07:08 AM.

  3. #3
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Using c++17 optional<>

    Note for any viewer considering this, some c++17 documentation for optional<> examples returns the optional value via {}. In MS VS2017 this causes the data value to be returned via a copy - not a move. Consider

    Code:
    #include <iostream>
    #include <vector>
    #include <optional>
    using namespace std;
    using iVect = vector<int>;
    
    iVect vectv()
    {
    	iVect v4;
    	v4.resize(400);
    
    	cout << "v4 in function vectv" << endl;
    	cout << hex << v4.data() << dec << " " << v4.size() << endl;
    
    	return {v4};
    }
    
    optional<iVect> vectc()
    {
    	iVect v5;
    	v5.resize(500);
    
    	cout << "v5 in function vectc - optional {}" << endl;
    	cout << hex << v5.data() << dec << " " << v5.size() << endl;
    
    	return {v5};
    }
    
    optional<iVect> vectm()
    {
    	iVect v6;
    	v6.resize(600);
    
    	cout << "v6 in function vectm - optional" << endl;
    	cout << hex << v6.data() << dec << " " << v6.size() << endl;
    
    	return v6;
    }
    
    optional<iVect> vectm2()
    {
    	iVect v7;
    	v7.resize(700);
    
    	cout << "v7 in function vectm2 - optional {move}" << endl;
    	cout << hex << v7.data() << dec << " " << v7.size() << endl;
    
    	return {move(v7)};
    }
    
    int main()
    {
    	auto v1 = vectv();
    	cout << "v1 in main via return vect\n" << hex << v1.data() << dec << " " << v1.size() << endl << endl;
    
    	auto v2 = vectc();
    	cout << "v2 in main via return optional {}\n" << hex << v2->data() << dec << " " << v2->size() << endl << endl;
    
    	auto v3 = vectm();
    	cout << "v3 in main via return optional\n" << hex << v3->data() << dec << " " << v3->size() << endl << endl;
    
    	auto v4 = vectm2();
    	cout << "v4 in main via return optional {move}\n" << hex << v4->data() << dec << " " << v4->size() << endl;
    }
    This produces the output on my computer

    Code:
    v4 in function vectv
    0092AEA0 400
    v1 in main via return vect
    0092AEA0 400
    
    v5 in function vectc - optional {}
    0092B4E8 500
    v2 in main via return optional {}
    0092BCC0 500
    
    v6 in function vectm - optional
    00936BE8 600
    v3 in main via return optional
    00936BE8 600
    
    v7 in function vectm2 - optional {move}
    00937550 700
    v4 in main via return optional {move}
    00937550 700
    This shows that

    for vectv() , the data is returned via move as the two addresses are the same (the one in the function and the one in main()).

    for vectc() using return {}, the data is returned via a copy of the underlying data as the two addresses are different.

    for vectm() , the data is returned via move as the two addresses are the same.

    for vectm2() using return {move()}, the data us returned via move as the two addresses are the same.

    This shows that for MS VS2017 return {} shouldn't be used when returning data for type optional<>. It won't matter if a simple data type is returned (eg int), but could have considerable performance issues if the return type uses dynamic memory (eg any STL container, string etc).

    If the syntax return {} is required for data for optional<>, then this should be of the form {move()} as appropriate.

    Doh!
    Last edited by 2kaud; February 8th, 2018 at 05:11 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured