簡體   English   中英

初始化不可復制和不可移動類的元組

[英]Initialize a tuple of non-copyable and non-movable classes

考慮具有唯一自定義構造函數的類A:

class A
{
public:
    A(float) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

還有另一個類B,其中包含A的元組(為簡單起見,請使其成為唯一的元組成員):

class B
{
public:
    B() : ta(0.0f) {} // ta initialization OK

private:
    std::tuple<A> ta;
};

現在我們可以聲明B的對象,並且可以正常工作:

B b;

但是,如果A的構造函數具有多個參數,該如何做呢?

class A
{
public:
    A(float, int) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

class B
{
public:
//  B() : ta(0.0f, 1) {} // Compilation errors
//  B() : ta({0.0f, 1}) {} // Compilation errors
//  B() : ta{0.0f, 1} {} // Compilation errors
//  B() : ta(A(0.0f, 1)) {} // No constructor to copy or move A

private:
    std::tuple<A> ta;
};

B b;

std::make_tuplestd::forward_as_tuple和其他類似的方法都不能解決問題,因為默認情況下, A復制,構造函數和移動構造器均被禁用。

std::tuple很少有用於就地構建其成員的設施。 通常,初始化tuple是通過從其組件對象復制/移動。

它確實允許將構造函數參數隱式轉換為它們各自的參數。 但這只是參數和tuple成員之間的1:1關系。 構造函數參數和tuple成員之間沒有多對一的關系。

可以允許從tuple本身隱式構造您的類型:

class A
{
public:
    A(float, int) {}
    A(const std::tuple<float, int> &tpl)
        : A(std::get<0>(tpl), std::get<1>(tpl)) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

因此,您可以像這樣構造一個tuple

class B
{
public:
    B() : ta(std::tuple<float, int>(0.0f, 1)) {}

private:
    std::tuple<A> ta;
};

如果要使用更深入的元編程,則可能仍可以創建一組構造函數,以允許從其類型與任何可用構造函數匹配的tuple構造類型:

class A
{
public:
    A(float, int) {}

    template<typename ...Args>
    A(const std::tuple<Args...> &args) : A(args, std::index_sequence_for<Args...>{}) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;

    template<typename ...Args, std::size_t ...Is>
    A(const std::tuple<Args...> &args, std::index_sequence<Is...>) 
        : A(std::get<Is>(args)...) {}
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM