I use something like this:
template <typename T>
const T* temp_ptr(const T&& x) { return &x; }
Used like this:
foo(temp_ptr(Key{}));
This is very useful when dealing with certain legacy APIs. DirectX 11 in particular frequently takes parameter aggregating structs by const T*
and it's convenient to create and pass them inline. I don't think there's anything wrong with this idiom unlike some of the commenters here, although I'd prefer if those APIs just took a const reference and handled optional arguments differently.
Here's an example D3D11 API call where this is very useful:
vector<Vec3f> verts;
...
ID3D11BufferPtr vbuf;
d3dDevice->CreateBuffer(
temp_ptr(CD3D11_BUFFER_DESC{byteSize(verts), D3D11_BIND_VERTEX_BUFFER}),
temp_ptr(D3D11_SUBRESOURCE_DATA{data(verts)}), &vbuf);
For calling ID3D11Device::CreateBuffer()
to create a vertex buffer.
On larger projects I might write wrappers for many of the D3D API calls which make them more convenient to call in a modern C++ style but for small standalone sample projects that I want to have minimum extra code or dependencies I find this very useful.
Another trick I've used in the past that works is:
foo(std::data({Key{}}));
But I don't particularly recommend this as I think the intent is unclear and relies on a bit too much knowledge of how initializer lists work. A variation is useful if you need to pass a temporary 'array' though:
d3dDeviceContext->ClearRenderTargetView(rendertarget, data({0.0f, 0.0f, 0.0f, 0.0f}));
For calling an API like ID3D11DeviceContext::ClearRenderTargetView()
.
void foo(const Key &key){ foo(&key); }
? – Maedac++
at once? – Carabinierenew Key
and delete it afterwards or use a smart pointer. – Reetanullptr
, or omit providing an argument. – Haymanconst
pointer to a temporary in this type of context. It's safe, well defined and avoids introducing unnecessary named temporaries. – Polycythemia