I have code here:
#include <string>
#include <iostream>
#include <initializer_list>
template <typename T>
class Test
{
public:
Test(std::initializer_list<T> l)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Test(const Test<T>& copy)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Test(Test&&) = delete;
Test() = delete;
};
void f(const Test<Test<std::string>>& x)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void f(const Test<std::string>& x)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
f(Test<Test<std::string>>{x});
}
int main()
{
Test<std::string> t1 {"lol"};
f(t1);
return 0;
}
I try to compile this with GCC 7.3.0 on my linux mint 19 with command:
g++ -std=c++11 -O0 test.cpp -o test -Wall -pedantic
Compilation fails with error that this call:
f(Test<Test<std::string>>{x});
Requires move constructor, but it's deleted. I always thought that move and copy constructors are equivalent in terms of compilation cause rvalue can be bound to const reference, but overload with explicitly defined rvalue reference is just prioritized in overload resolution. This is first time i see that compiler actually requires move constuctor and won't just use copy instead. Why? Am i missing something?
deleted function is declared. It will be included in the overload set during name lookup, so you are actually trying to call thedeleted function. If you defined a copy constructor and simply didn't declare a move constructor at all, you would get the behaviour you expect. - BoBTFish