From: Vidar Hasfjord on
On Mar 30, 4:49 pm, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
> Hi,
>
> I need to provide a set of parameters to a function where one or more
> can be optional. Standard C++ can only provide default values for the
> last parameters and a default value representing N/A for references is
> not quite pleasant.
>
> I came up with an idea of overloading the optional parameters. Please
> give me your feedback.
>
> class SomeClass
> {
> public:
>
> void fnc( int& a );
> void fnc( int& a, int& b );
> void fnc( int& a, int& b, int& c );
>
> // Now insert a pointer if we want to disable (b).
> void fnc( int& a, int* b, int& c );
>
> };
>
> int main()
> {
> SomeClass sc;
> int a, b, c;
>
> // Just want to provide (a).
> sc.fnc( a );
>
> // Just want to provide (a) and (b).
> sc.fnc( a, b );
>
> // Just want to provide (a) and (c) but not (b).
> // Tricky to get right normally, but with this overloading
> // it works!
> sc.fnc( a, NULL, c );
>
> }
>
> Is this way to provide optional parameters ok, or will I bump into
> trouble later I haven't foreseen here?

Rather than use the type-unsafe NULL pointer to do this, you should
define your own singleton type, e.g. Default.

> My next question is; is there a way to use some technique like traits or
> similar to make sure at compile time that (b) for sure is NULL?

If you use a dedicated type for place-holders for default values then
you avoid this problem altogether. For example:

namespace some_namespace {

// The "default" singleton

struct Default {} const default;

// Our demo function

void f (int& a, int& b, int& c);

// Allow defaults in any position.
// (2^n - 1 overloads, where n is the argument count)

void f (int& a, int& b, Default);
void f (int& a, Default b, int& c);
void f (int& a, Default, Default);
void f (Default, int& b, int& c);
void f (Default, int& b, Default);
void f (Default, Default, int& c);
void f (Default, Default, Default);

// Allow trailing defaults to be omitted.
// (2^(n - 1) + ... + 2^1 additional overloads)

void f (int& a);
void f (Default);
void f (int& a, int& b);
void f (int& a, Default);
void f (Default, int& b);
void f (Default, Default);
}


void test() {
int a, b, c;
using namespace some_namespace;

// Just want to provide (a).

f (a);
f (a, default);
f (a, default, default);

// Just want to provide (a) and (b).

f (a, b);
f (a, b, default);

// Just want to provide (a) and (c), but not (b).

f (a, default, c);
}

While I think this idea has merit, the problem with it is that you
need a lot of overloads to be fully general, as demonstrated above.

Regards,
Vidar Hasfjord


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: DeMarcus on
Daniel T. wrote:
> In article <4bb1fa6e$0$279$14726298(a)news.sunsite.dk>,
> DeMarcus <use_my_alias_here(a)hotmail.com> wrote:
>
>> Hi,
>>
>> I need to provide a set of parameters to a function where one or more
>> can be optional. Standard C++ can only provide default values for the
>> last parameters and a default value representing N/A for references is
>> not quite pleasant.
>>
>> I came up with an idea of overloading the optional parameters. Please
>> give me your feedback.
>>
>> class SomeClass
>> {
>> public:
>>
>> void fnc( int& a );
>> void fnc( int& a, int& b );
>> void fnc( int& a, int& b, int& c );
>>
>> // Now insert a pointer if we want to disable (b).
>> void fnc( int& a, int* b, int& c );
>> };
>>
>> int main()
>> {
>> SomeClass sc;
>> int a, b, c;
>>
>> // Just want to provide (a).
>> sc.fnc( a );
>>
>> // Just want to provide (a) and (b).
>> sc.fnc( a, b );
>>
>> // Just want to provide (a) and (c) but not (b).
>> // Tricky to get right normally, but with this overloading
>> // it works!
>> sc.fnc( a, NULL, c );
>>
>> }
>>
>> Is this way to provide optional parameters ok, or will I bump into
>> trouble later I haven't foreseen here?
>
> Don't beat yourself up like this, just do:
>
> class SomeClass {
> public:
> void func_a(int a);
> void func_ab(int a, int b);
> void func_ac(int a, int c);
> void func_abc(int a, int b, int c);
> };
>
> It will be a lot clearer at the calling site what is going on too.
>

Hm, you have a point, but when fnc is a constructor it will be problematic.




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: DeMarcus on
Seungbeom Kim wrote:
> On 2010-03-30 08:49, DeMarcus wrote:
>> Hi,
>>
>> I need to provide a set of parameters to a function where one or more
>> can be optional. Standard C++ can only provide default values for the
>> last parameters and a default value representing N/A for references is
>> not quite pleasant.
>>
>> I came up with an idea of overloading the optional parameters. Please
>> give me your feedback.
>>
>> class SomeClass
>> {
>> public:
>>
>> void fnc( int& a );
>> void fnc( int& a, int& b );
>> void fnc( int& a, int& b, int& c );
>>
>> // Now insert a pointer if we want to disable (b).
>> void fnc( int& a, int* b, int& c );
>> };
>
> Doesn't the last overload have to deal with non-null values of b anyway?
> Then I don't see the value of having the third overload separately.
>

The point is that the last overload allows us to write
fnc( a, NULL, c );
which the others don't. The point is that in the last overload we don't
use b, why it's important that we could check in compile time that b for
sure is NULL (if it's possible).


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Brian McKeever on
On Mar 30, 8:49 am, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
> class SomeClass
> {
> public:
>
> void fnc( int& a );
> void fnc( int& a, int& b );
> void fnc( int& a, int& b, int& c );
>
> // Now insert a pointer if we want to disable (b).
> void fnc( int& a, int* b, int& c );
> };


> Is this way to provide optional parameters ok, or will I bump into
> trouble later I haven't foreseen here?

You may run into trouble in the specific case where your parameters
are integer types. Since NULL is usually just a #define for 0, it's
possible to find yourself in a situation where the compiler selects a
different overload than the one you intend. For instance, if fnc took
its parameters by value or const reference, a non-pointer version
would be selected over one involving int*.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel T. on
DeMarcus <use_my_alias_here(a)hotmail.com> wrote:
> Daniel T. wrote:
>> DeMarcus <use_my_alias_here(a)hotmail.com> wrote:
>>
>>> I need to provide a set of parameters to a function where one or
>>> more can be optional. Standard C++ can only provide default values
>>> for the last parameters and a default value representing N/A for
>>> references is not quite pleasant.
>>>
>>> I came up with an idea of overloading the optional parameters.
>>> Please give me your feedback.
>>>
>>> class SomeClass
>>> {
>>> public:
>>>
>>> void fnc( int& a );
>>> void fnc( int& a, int& b );
>>> void fnc( int& a, int& b, int& c );
>>>
>>> // Now insert a pointer if we want to disable (b).
>>> void fnc( int& a, int* b, int& c );
>>> };
>>>
>>> int main()
>>> {
>>> SomeClass sc;
>>> int a, b, c;
>>>
>>> // Just want to provide (a).
>>> sc.fnc( a );
>>>
>>> // Just want to provide (a) and (b).
>>> sc.fnc( a, b );
>>>
>>> // Just want to provide (a) and (c) but not (b).
>>> // Tricky to get right normally, but with this overloading
>>> // it works!
>>> sc.fnc( a, NULL, c );
>>>
>>> }
>>>
>>> Is this way to provide optional parameters ok, or will I bump into
>>> trouble later I haven't foreseen here?
>>
>> Don't beat yourself up like this, just do:
>>
>> class SomeClass {
>> public:
>> void func_a(int a);
>> void func_ab(int a, int b);
>> void func_ac(int a, int c);
>> void func_abc(int a, int b, int c);
>> };
>>
>> It will be a lot clearer at the calling site what is going on too.
>
> Hm, you have a point, but when fnc is a constructor it will be
> problematic.

That's what the named constructor idiom is for:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]