How to mark a function as invalidating its argument

I have a function fthat takes a pointer vector. As soon as the function fends, these pointers are no longer valid. Please note: there is no real need to change the vector itself, I just want to encourage callers not to use pointers after the call f. For fthere are three possible signatures:

Transition Signature

void f(vector<void*> &&v); // because the pointers in v are no longer valid. 
// This signature also allows me to have f call clear() on v.

Signature const

void f(const vector<void*> &v); // because the pointers in v are no longer valid,
// but we don't have to change the vector v.

Signature Pointer

void f(vector<void*> *v); // The functino modifies v in a predictable way 
// (it clears it). A pointer is used instead of a reference so that
// calls to the function will have a '&' which clearly shows to the reader
// that this function modifies its argument. '*' is different from '&&' since '&&' 
// may imply "do not use v, but it is unknown how it will be modified" while 
// '*' implies a clear semantic for how v is changed.

Which signature is more idiomatic for use in C ++ 11?

+4
source share
6 answers

What about

void f(vector<void*> v);

And use it:

vector<void*> myVec = /*...*/;
f(std::move(myVec));

f , . , f.

f ( in/out), . in/out . . , .

+2

, , .

template<class T>
struct invalidates_contained_pointers;

template<class T>
invalidates_contained_pointers<T>* contents_will_be_invalidated(T* ptr) {
    return reinterpret_cast<invalidates_contained_pointers<T>*>(ptr);
}

void f(invalidates_contained_pointers<vector<void*>> *v){
    auto pv = reinterpret_cast<vector<void*> *>(v);
    // ...
}

f(contents_will_be_invalidated(&vec));

.

+2

: . , "", : , promises, f(..) : const.

:

  • , , const

  • , , -const-, " , f(...)".

+1

, - " ". :

void f(vector<void*> &v)
{
  // ... use v ...
  v.clear(); // encourage callers not to use the pointers after the call
}
+1

f , ( , ). intederminate.

, f . , lvalue rvalue ; lvalue .

+1

: vector<void*> * lvalue . const vector<void*> & lvalues ​​ r. vector<void*> && rvalues.

Based on your question, your function makes sense to be called with lvalues ​​or rvalues, so it const vector<void*> &is an obvious choice.

There is no way to indicate through the type system that the caller should stop using the contained pointers, and you should not try to indicate this through the type system. Indicate this through the documentation.

0
source

All Articles