代码之家  ›  专栏  ›  技术社区  ›  David Stone

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

  •  8
  • David Stone  · 技术社区  · 11 年前
    #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);
    }
    

    是否可以在不调用initializer_list构造函数的情况下将C(一种不可复制、不可移动的类型)构造成函数参数或函数返回值?

    1 回复  |  直到 11 年前
        1
  •  2
  •   Jonathan Wakely    11 年前

    只有你能改变 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 << "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();
    }
    

    这将打印:

    int
    int