#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?
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
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