Olzhas Zhumabek Olzhas Zhumabek - 2 months ago 8
C++ Question

Force compiler to choose copy constructor with const T& as a parameter

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.

Answer

Add another constructor:

foo(foo& other) : foo( const_cast<const foo&>(other))
{
}

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

Comments