I have following code:
#include <iostream>
class Dog
{
public:
Dog() : ptr(nullptr)
{
std::cout << "ctor" << std::endl;
}
Dog(const Dog&) = delete;
Dog(Dog&&) = delete;
inline operator void*() const
{
std::cout << "conversion op" << std::endl;
return ptr;
}
private:
void* ptr;
};
void dosomething_buf(void*)
{
}
void dosomething(const Dog& d)
{
dosomething_buf(d);
}
int main()
{
Dog d;
dosomething(d);
}
This code works as intended and calls ctor and implicit conversion operator once.
However if I change the signature of dosomething_buf(void*)
to void dosomething_buf(...);
I get following compile-error:
[build] [ 50%] Building CXX object CMakeFiles/playground.dir/test.cpp.o
[build] /media/rbs42/data/Gebos/RBS42/PlayGround/test.cpp: In function ‘void dosomething(const Dog&)’:
[build] /media/rbs42/data/Gebos/RBS42/PlayGround/test.cpp:31:20: error: use of deleted function ‘Dog::Dog(const Dog&)’
[build] dosomething_buf(d);
[build] ^
[build] /media/rbs42/data/Gebos/RBS42/PlayGround/test.cpp:11:5: note: declared here
[build] Dog(const Dog&) = delete;
[build] ^~~
Why does the compiler call the copy-ctor?
Why would you expect the void*
conversion operator to be invoked at all, since there's no void*
argument anymore?
C-style variadic functions (which, by they way, are not recommended in C++ since we have varadic templates) take an arbitrary number of arguments by value. When calling dosomething_buf(d)
, you're copying d
to initialize one of the variadic arguments.