在不调用initializer_list构造函数的情况下,将不可复制、不可移动的类型构造为函数形参

Constructing a non-copyable, non-movable type into a function parameter without invoking initializer_list constructor

本文关键字:类型 可移动 形参 函数 可复制 initializer 调用 list 构造函数 情况下      更新时间:2023-10-16
#include <initializer_list>
#include <iostream>
namespace {
class C {
public:
    C(C const &) = delete;
    C(C &&) = delete;
    C(int) {
        std::cout << "intn";
    }
    C(std::initializer_list<int>) {
        std::cout << "initializern";
    }
};
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);
}
能否在不调用initializer_list构造函数的情况下,将不可复制、不可移动的C类型构造为函数参数或函数返回值?

这只有在你可以改变C以便选择所需的构造函数而不是初始化列表构造函数时才有可能,例如,通过将参数类型包装在不能转换为初始化列表构造函数的元素类型的东西中:

#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 << "intn";
    }
    C(std::initializer_list<int>) {
        std::cout << "initializern";
    }
};
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();
}
这个打印

:

int
int