Is it possible to specify an empty std::vector as a default parameter?

omatai picture omatai · May 16, 2012 · Viewed 15.9k times · Source

I have been reading through this similar question and find myself less than satisfied with the responses. I don't have a simple function called "foo"; I have a much more complex function which has very real dangers if parameters are not supplied judiciously. It seems preferable to me for the function to enforce its own rules and ensure system robustness than to lean towards semantic niceties which insist on "one function, one thing to do". I think the favoured responses given to that question reflect programming idealism taken too far, not the reality of certain situations.

What I face is:

void DoSomethingVeryComplex( const CRect bounds, CPoint startPoint = CPoint(-1,-1) );

Now this happens to satisfy the semantic rules - it is doing some thing, not several things. The one thing it is doing happens to be complex, and multi-staged, but it is still one thing.

For that complex thing, it is recommended that the user supply the bounds, and let the function determine its own starting point. Advanced users might want to do the considerable math to determine a specific alternative starting point and supply that... but users beware.

And now I have come to see that on rare occasions, it makes sense to supply not one, but several starting points. This changes nothing in the semantic concept of the process involved, because the process is one which spreads from one point to neighbours, to neighbours of neighbours, and so on. So starting from many points is a natural extension.

Accordingly, I would prefer to specify:

void DoSomethingVeryComplex( const CRect bounds,
                             const std::vector<CPoint> startPoint /* = empty" */ );

so that if the vector is empty, the function determines the start point as before, and if there are any points in the vector, they are used as start point(s).

Is there a C++ syntax available which allows me to do this - to specify an empty array as a default parameter?

Answer

chris picture chris · May 16, 2012

In C++11, it's simplest:

const std::vector<CPoint> startPoint = {}

Before that, this will work:

const std::vector<CPoint> startPoint = std::vector<CPoint>()

Both of these invoke the default constructor, which creates an empty vector. Note that the same syntax can be used to call other constructors as well, as long as you fill in the appropriate arguments.

//this one has 5 default-constructed CPoints
const std::vector<CPoint> startPoint = std::vector<CPoint>(5) 

In C++11, you can even fill out a default vector:

const std::vector<CPoint> startPoint = {CPoint(1, 2), CPoint(4, 5), CPoint(3, 9)}

If you want that kind of capability for your own classes, here's a link on how it works.