user3819404
user3819404

Reputation: 621

Avoid exposing static variable for a default function argument

I have a function foo() that updates a global CAtlList. Now I want to reuse foo to update another list. Currently I achieve this using a default argument.

 //header.h
 extern CAtlList<data> globalList;
 void foo(CAtlList<data> &somelist = globalList);

 //file1.cpp
 CAtlList<data> globalList;
 void foo(CAtlList<data> &somelist)
 {
    //update somelist
 }

 //file2.cpp
 #include "header.h" 
 foo();

and 

 CAtlList<data> anotherList;
 foo(anotherList);
//use anotherList

But for the default scenario foo takes globalList by reference, which means globalList must be visible at the point of declaration. I had to expose and add an extern declaration of globalList for that to happen.

I'd rather not expose it, is it at all possible?

Upvotes: 1

Views: 101

Answers (2)

user48956
user48956

Reputation: 15788

I don't know you can avoid declaring a variable that's referenced as a default. However, you could simply overload the function:

 //file1.h
 void foo();
 void foo(CAtlList<data> &somelist);

 //file1.cpp
 #include "file2.h"

 CAtlList<data> globalList; // Local scope only

 void foo(CAtlList<data> &somelist)
 {
    //update somelist
 }

 void foo()
 {
    foo(globalList);
 }

A more modern way is to use the 'optional' class that's part of the C++ library:

http://en.cppreference.com/w/cpp/utility/optional

//file1.h
#include <optional>
void foo(optional<CAtlList<data>> &somelist);

//file1.cpp
#include "file1.h"

CAtlList<data> globalList; // Local scope only

void foo(optional<CAtlList<data>> &somelist){
   if (somelist.has_value()) { /* update somelist */ }
   else { /* update globalList */ }
}

However, I suspect that this will break the existing dependencies. If there are few and easy to fix, this is probably the way.

The other comments are also correct. You should try and avoid the use of global state wherever possible - its a symptom of poor design.

Upvotes: 0

davidbak
davidbak

Reputation: 6009

Use an overload, not a default parameter.

void foo();
void foo(CAtlList<data> &somelist);

It costs you 4 short lines of code in the .cpp: The body of the parameterless foo calling the 1-parameter foo with the correct argument. That's the total cost to get the expressiveness you desire. A default parameter is not the tool for your job.

Upvotes: 2

Related Questions