I'm writing a class where I have a templated constructor and copy constructor. Every time I want to call copy constructor with non const object, templated constructor gets chosen. How can I force compiler to choose copy constructor?
Here is the mcve:
#include <iostream>
struct foo
{
foo()
{
std::cout << "def constructor is invoked\n";
}
foo(const foo& other)
{
std::cout << "copy constructor is invoked\n";
}
template <typename T>
foo(T&& value)
{
std::cout << "templated constructor is invoked\n";
}
};
int main()
{
foo first;
foo second(first);
}
Deleting a function is not what I want.
When we create our own copy constructor, we pass an object by reference and we generally pass it as a const reference. One reason for passing const reference is, we should use const in C++ wherever possible so that objects are not accidentally modified.
Copy Constructor in C++ ClassName (const ClassName &old_obj); Copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. Copy constructor takes a reference to an object of the same class as an argument.
Default Copy Constructors: When a copy constructor is not defined, the C++ compiler automatically supplies with its self-generated constructor that copies the values of the object to the new object.
In C++, a Copy Constructor may be called for the following cases: 1) When an object of the class is returned by value. 2) When an object of the class is passed (to a function) by value as an argument. 3) When an object is constructed based on another object of the same class.
Add another constructor:
foo(foo& other) : foo( const_cast<const foo&>(other)) // for non-const lvalues
{
}
The first
object in your example code is a non-const lvalue, therefore the compiler prefers foo(foo&)
over foo(const &)
. The former is provided by the template (with T=foo&
) and therefore is selected.
This solution involves providing a (non-template) constructor for foo(foo&)
which then delegates construction to the copy constructor by casting it to a reference-to-const
Update, I've just realised that a foo
rvalue will be taken by the template also. There are a number of options here, but I guess the simplest is to also add a delegate for foo(foo&&)
, similar to the one above
foo(foo&& other) : foo( const_cast<const foo&>(other)) // for rvalues
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With