optional argument of a function

Jan 3, 2020 at 2:11am
How to have optional argument of a function, being explicitly meant so with condition rule:

. if argument/parameter exists, it's as is supposed to be

. if it does not, the function does not outright have it, as if its declaration having the total number of argument substracted with 1, which means without that argument/parameter at all

without getting double function writing by overload fn.
it's at least 95 lines
Last edited on Jan 3, 2020 at 2:34am
Jan 3, 2020 at 2:18am
1
2
3
4
5
6
7
8
9
10
#include <iostream>

void foo(int) { std::cout << "foo(int)\n"; }
void foo() { std::cout << "foo()\n"; }

int main()
{
  foo(2); // calls foo(int)
  foo();  // calls foo()
}
Last edited on Jan 3, 2020 at 2:19am
Jan 3, 2020 at 2:45am
Without getting double function writing by overload fn.

Either you added this in later, or I misread:

Your other option is to create a set of overloads via default arguments:
1
2
3
4
5
6
7
8
9
#include <iostream>

void foo(int x = 0) { std::cout << x << '\n'; }

int main()
{
  foo(2); // calls foo(2)
  foo();  // calls foo(0)
}
Jan 3, 2020 at 3:26am
Your other option is to create a set of overloads via default arguments

Default arguments don't create a set of overloads.
Jan 3, 2020 at 3:41am
mbozzi wrote:
or I misread:
You didn't misread it.
Jan 3, 2020 at 4:05am
@dutch Right, thanks. There is still only one function.
Last edited on Jan 3, 2020 at 4:05am
Jan 3, 2020 at 4:34am
@mbozzi, Default args are a little weird. As you know, they need to appear in the header file so that the compiler can fill in the value in the actual call with only the info in the header. I've noticed that the standard library seems to be removing default arguments in some places. I wonder what the reason for that is and what best practices have to say about it.
Jan 3, 2020 at 5:27am
> How to have optional argument of a function, being explicitly meant so with condition rule:
> if argument/parameter exists, it's as is supposed to be
> if it does not, the function does not outright have it,

Use a parameter pack to represent the optional arguments, perhaps.
https://en.cppreference.com/w/cpp/language/parameter_pack

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <typeinfo>

struct print
{
    template < typename T > const print& operator<< ( T&& v ) const
    {
        std::cout << "      " << v << "  (type: " << typeid(T).name() << ")\n" ;
        return *this ;
    }
};

template < typename... OPTIONAL_ARGS > // 
void foo( int a, const char* b, OPTIONAL_ARGS&& ... optional_args /* zero or more optional  arguments */ )
{
    std::cout << "foo:\n  a == " << a
              << "  b == " << ( b ? b : "nullptr" ) << '\n' ;

    std::cout << "  #additional args: " << sizeof...(optional_args) << '\n' ;
    ( print() << ... << optional_args ) ;

    std::cout << "\n-----------------\n" ;
}

struct xyz
{
    int v = 0 ;
    friend std::ostream& operator<< ( std::ostream& stm, xyz x )
    { return stm << "::xyz{" << x.v  << '}' ; }
};

int main()
{
    foo( 23, "abcd" ) ;
    foo( 7890, "ijkl", 1234, 56.78, xyz{9} ) ;
    foo( 12345, "mnop", 56789, 0.1234, "qrst", +"uvwx",  xyz{56789} ) ;
}

http://coliru.stacked-crooked.com/a/3dff18e574c3c6d8
Jan 3, 2020 at 1:10pm
JLBorges, could you please explain me how does row 20 work?

( print() << ... << optional_args ) ;

What are those round parentheses and why we need them?
Jan 3, 2020 at 2:09pm
It is a fold-expression which came with C++17. https://en.cppreference.com/w/cpp/language/fold

A fold-expression always starts with an open parenthesis and ends with a closing parenthesis;
the parentheses are an integral part of the fold-expression.

What we have is 4) binary left fold https://en.cppreference.com/w/cpp/language/fold#Explanation
where init I is an anonymous object of type print
Last edited on Jan 3, 2020 at 2:09pm
Jan 3, 2020 at 3:30pm
Thank you a lot, JLBorges.
So many thing to learn…
Jan 4, 2020 at 8:16am
Thanks great worthwhile tips
Jan 7, 2020 at 12:50am
dutch wrote:
I've noticed that the standard library seems to be removing default arguments in some places. I wonder what the reason for that is and what best practices have to say about it.

I haven't noticed any such change, so I don't know. Do you have any specific example in mind?

Jan 7, 2020 at 1:47am
@mbozzi, I've noticed it mostly in ctors. Here's a couple of examples:

On this page from cppreference for the basic_string ctor, form number 3 before C++17 has a default argument for count, but since C++17 it has two separate ctors.

https://en.cppreference.com/w/cpp/string/basic_string/basic_string

On these pages for vector and list, form number 3 has a default argument for value which was removed in C++11.

https://en.cppreference.com/w/cpp/container/vector/vector
https://en.cppreference.com/w/cpp/container/list/list

On this page for basic_istringstream, form number 2 has it's default argument removed for C++11.

https://en.cppreference.com/w/cpp/io/basic_istringstream/basic_istringstream
Jan 7, 2020 at 6:02am
On this page from cppreference for the basic_string ctor, form number 3 before C++17 has a default argument for count, but since C++17 it has two separate ctors.
Constructors for containers in the standard library come in pairs. Typically, one constructor takes an allocator argument and the other doesn't. In this case, one was missing. The new constructor allows
std::string(str, pos, alloc)
instead of the equivalent, more verbose
std::string(str, pos, std::string::npos, alloc).

The change is traced to LWG issue 2583:
https://wg21.link/lwg2583

On these pages for vector and list, form number 3 has a default argument for value which was removed in C++11.
For both vector and list, the addition of constructor 4 would cause ambiguity if the default arguments remained; there is a difference in semantics between the two overloads (in both cases, #4 doesn't make copies).

On this page for basic_istringstream, form number 2 has it's default argument removed for C++11.
basic_istringstream had an explicit default constructor (i.e., #2).

The change was proposed for C++11 by P0935:
https://wg21.link/p0935 (grep that document for istringstream.)
Last edited on Jan 7, 2020 at 6:41am
Jan 7, 2020 at 7:28am
@mbozzi, Thank you. That explains it. And that wg21.link redirect site is interesting in itself. :)
Topic archived. No new replies allowed.