Constructing a non-copyable, non-movable type into a function parameter without invoking initializer_list constructor
c++, c++11, initializer-list
Solution
It's only possible if you can change `C` so the desired constructor can be chosen instead of the initializer-list constructor, e.g. by wrapping the argument type in something that isn't convertible to the element type of the initializer-list constructor:
#include <initializer_list>
#include <iostream>
namespace {
template<class T>
struct wrap
{
T value;
};
class C {
public:
C(C const &) = delete;
C(C &&) = delete;
C(wrap<int>) {
std::cout << "int\n";
}
C(std::initializer_list<int>) {
std::cout << "initializer\n";
}
};
void f(C) {
}
// Compiles and prints "int" when called
C g() { return {wrap<int>{0}}; }
} // namespace
int main() {
// Compiles and prints "int"
f({wrap<int>{0}});
g();
}
This prints:
int
int
Problem
``` #include <initializer_list> #include <iostream> namespace { class C { public: C(C const &) = delete; C(C &&) = delete; C(int) { std::cout << "int\n"; } C(std::initializer_list<int>) { std::cout << "initializer\n"; } }; void f(C) { } // Compiles and prints "initializer" when called C g() { return {0}; } // Fails to compile // C h() { return 0; } } // namespace int main() { // Compiles and prints "initializer" f({0}); // Fails to compile // f(0); } ``` Is it possible to construct C, a non-copyable, non-movable type, into a function parameter or function return value without invoking the initializer_list constructor?