Quick question:

Normally when I have a function, I can make one or more of the 'last' arguments as defaults, for example:

string whatever( int a, string b="NONE" )
{
//blah, blah, blah
string temp= "WHATEVER";
return temp;
}

The benefit is that I can have one function and I can do logic in there based on whether my parameter has the default or has something else.

I would like to do the same thing, but with a parameter that is a container. How do I do it?

string whateverTwo( int a, vector<string> defaultV = ????)
{
 
//whatever
string temp= "WHATEVER";
return temp;
}

I want this so that I can either pass in the vector or not. I know that I of course can make 2 different functions, but wanted to see if I could do a default instead. Any thoughts?

Dani AI

Generated

wanted an optional STL container parameter and logic that knows whether the caller supplied it. Two important design choices determine the right pattern: (A) whether an omitted parameter must be distinguishable from an explicitly passed empty container, and (B) whether the function needs ownership/mutation of the container. 's pointer suggestion solves (A). 's point about avoiding unnecessary copies is also relevant.

A simple, common pattern when "omitted" can be treated the same as an empty container is to use a const reference with a default-constructed container:

std::string whateverTwo(int a, const std::vector<std::string>& v = std::vector<std::string>()) {
    // read-only use of v; make a local copy only if modification/ownership is needed
}

This avoids copies for lvalue arguments and is valid in pre-C++11 code.

When the function needs ownership or will mutate the container, prefer pass-by-value (C++11+), which plays nicely with move semantics:

std::string whateverTwo(int a, std::vector<std::string> v = {}) {
    // v can be modified freely; callers that pass temporaries will move instead of copy
}

This keeps the API simple while allowing efficient moves for rvalue callers.

When it is necessary to distinguish "argument omitted" from "argument explicitly passed as empty", use an optional-like type. Pointer semantics (as suggested) work, but in modern C++ prefer std::optional:

std::string whateverTwo(int a, std::optional<std::vector<std::string>> v = std::nullopt) {
    if (!v) { /* omitted case */ } else { /* caller supplied vector (possibly empty) */ }
}

Choose the pattern that matches the API semantics: const-ref for read-only, pass-by-value for ownership/mutating needs with move support, and pointer/optional when omission must be detectable. Consider iterator-based overloads when only iteration is required.

Recommended Answers

All 2 Replies

Why not use a constant pointer to the vector? If the vector is not zero, then make a copy of it inside the function.

string whateverTwo( int a, const vector<string> *defaultV = 0) {
    vector<string> stringVector;
    if (defaultV != 0)
        stringVector = *defaultV;
    // ...
}

STL vector objects have their own default capacity, which is implementation dependent. You should be able to determine this value rather simply. Something like this should do.

vector<int> v;
cout << "default capacity of vectors in my STL implementation is " << v.capacity <<

Of course you can specify a capacity, if you desire.

vector<int> v(5);
cout << "the capacity of v is " << v.capacity();
cout << "the size of v is ";
if(v.empty())
cout << "zero" << endl;
else
cout << v.size();

You can also specify default values.

vector<int> v(5,0);
for(int i = 0; i < 5; ++i)
cout << "v[" << i << "] = " << v << ' ' ;

Data structures can be very big, meaning passing them back and forth by value can be costly. It's often wiser to pass them by reference, making them const references if you don't want the function to change any of the values in the structure being passed. So I'd declare the structure using my own defualt capacity and default all values to the desired default value and then pass that structure to a function by reference in it's current state.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.