tags:

views:

128

answers:

3

I have a function,

void test( vector<int>& vec );

How can I set the default argument for vec ? I have tried

void test( vector<int>& vec = vector<int>() );

But there's a warning "nonstandard extension used : 'default argument' : conversion from 'std::vector<_Ty>' to 'std::vector<_Ty> &'"

Is there a better way to do this ? Instead of

void test() {
    vector<int> dummy;
    test( dummy );
}

Regards, Voteforpedro

+7  A: 

Have you tried:

void test(const vector<int>& vec = vector<int>());

C++ does not allow temporaries to be bound to non-const references.

If you really to need to have a vector<int>& (not a const one), you can declare a static instance and use it as a default (thus non-temporary) value.

static vector<int> DEFAULT_VECTOR;

void test(vector<int>& vec = DEFAULT_VECTOR);

But beware, because DEFAULT_VECTOR will (can) be modified and won't reset on each call ! Not sure that this is what you really want.


Thanks to stinky472, here is a thread-safe alternative:

Instead of providing a default value, you might as well overload test() with a zero-parameter version which calls the other version:

void test()
{
  vector<int> vec;
  test(vec);
}
ereOn
+1 but I think it should be pointed out that 'test' would generally not be thread-safe were it to modify this 'DEFAULT_VECTOR'. It might be tedious, but I'd strongly recommend writing two functions for such needs (one can reuse the other): void test() {vector<int> temp; test(temp); }
@stinky472: Thanks, updated my answer.
ereOn
As a side note, there is a hacky way of getting a reference to a temporary if you can use some method on the latter that returns such a reference to itself... e.g. `operator=`. So, `void test(vector<int>` should work (the lifetime of the temporary is unaffected here and will remain sufficient to handle the call). But please don't do it :)
Pavel Minaev
+5  A: 

I find it questionable for a non-const reference argument to have a default value. What is this supposed to mean?

Commonly, a function taking a non-const reference means "I might change the argument". If the argument is optional why no pass a (non-const) pointer? That way, when callers don't want to pass an arguments, they can pass NULL.
(See here for more information on how to pass function arguments.)

Edit: Well, and of course, there's also overloading. Just add another overload which doesn't take this argument.

sbi
@sbi: You find it questionably?
DeadMG
@DeadMG: Are you referring to my broken grammar sub-system?
sbi
@sbi: Would I do something like that?
DeadMG
@DeadMG: From what I have seen...
sbi
+1  A: 

We cannot initialize mutable references to temporaries. Only const references allow this. What you are after is most likely this:

void test( const vector<int>& vec = vector<int>() );

Aside from avoiding undefined behavior, this makes the most sense logically and from a const-correctness perspective. If you wanted 'test' to modify the original vector being passed to it, you would not have been able to sensibly provide a default value. Thus it's obvious you are using 'vec' here for read-only purposes and should therefore make it a const reference.

You cannot initialize mutable references to temporaries directly, period. A temporary won't bind to a reference-to-non-const - if you try that, it's not U.B., it's ill-formed input (i.e. compiler error). VC++ lets you do this, but rightly notes that it is a language extension.
Pavel Minaev
@Pavel ah good point! I've seen nasty compilers that allowed this behavior like MSVC and past versions of CodeWarrior where the code built but crashed. I will modify the post accordingly for accuracy. Thanks for pointing it out.