2017-01-15 13 views
3

유일한 사용자 정의 생성자 클래스 A를 고려 비 복사 가능한 비 이동 수업의 튜플을 초기화 : (A)의 튜플을 포함

class A 
{ 
public: 
    A(float) {} 

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

그리고 다른 클래스 B, (그것이 유일한 튜플의 구성원이 될 수 있도록) 단순화를 위해 : 이제

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_tuple, std::forward_as_tuple 등 그 문제가 해결되지 않는 등, 기본, 복사 A의 이동 생성자를 사용할 수 없기 때문에.

+0

관련이있을 수 있습니다. http://stackoverflow.com/a/24888173 –

답변

3

std::tuple은 원내에서 멤버를 구성하기위한 기능이 거의 없습니다. tuple을 초기화하는 일반적으로 예상되는 방법은 해당 구성 요소 개체에서 복사/이동을 사용하는 것입니다.

생성자 매개 변수를 해당 인수로 암시 적으로 변환 할 수 있습니다. 그러나 이는 매개 변수와 tuple 회원 간의 1 : 1 관계에 불과합니다. 생성자 매개 변수와 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을 구성 할 수 있습니다 :

당신 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)...) {} 
};