This piece of code is a synthetic example extracted from a real world app.
This code doesn't make much sense, its only purpose is illustration and everything that is not relevant has been stripped.
#include <iostream> class st { public: int m = 1; st() { std::cout << "st()\n"; }; st(const st *source) { m = source->m; std::cout << "st(const st *source) " << m << "\n"; }; }; void Foo(const st& bar) { std::cout << "Foo" << "\n"; } int main() { st foo; const st* p = &foo; Foo(p); //(1) } Output
st() st(const st *source) 1 Foo The problem here is when I call the void Foo(const st& bar) function with a pointer to st as in the line with comment //(1) following happens:
As there is no Foo function that takes a st* as argument, a temporary object is created via the st(const st *) constructor and then a reference to this temporary object is passed to Foo. The code works as expected, but it took me a while to figure out why the st constructor was called.
I just wonder how this could have been prevented. I suppose either:
void Foo(const st& bar)should rather bevoid Foo(const st *bar)- or there shouldn't be a
st(const st *source)constructor but rather ast(const st & source)constructor. - or are there some C++ attributes that may generate warnings in such cases?
I'm using the C++20 standard.
st(const st *source)should handle thesource == nullptrsituation. Either by throwing, or behaving likest()constructor.