2017-10-03 1 views
6

이 코드를 고려std :: variant에 각 구조체의 생성자를 명시 적으로 작성하지 않아도됩니까?

#include <variant> 

struct x { 
    int y; 
}; 

int main() { 
    std::variant<x> v(std::in_place_type<x>, {3}); /*1*/ 
    return std::get<x>(v).y; 
} 

이 컴파일하지 않고도, 라인 /*1*/에서 {}을 제거 할 때 않는 경우에도 모두 "생성자 같은"형태의 집계 초기화

x a{3}; 
x b({3}); 

작품. 어떻게 든 내 이니셜 라이저가 내 실제 사례에서 사용될 수있는 각 구조체에 대한 지루한 보일러 플레이트 생성자를 작성하지 않고도 집계 초기화를 사용하여 구조체를 생성 할 수 있다는 것을 알고 있습니까?

내가 cppreference 당 두 개의 오버로드 (5), (6) 질문에 모두 말은

구축해, 지정된 대안 T와 와 변형이를 초기화로이, 어떻게 든 일을 기대 인수 에 포함 된 값 [...]

그 중요한 경우 내가 GCC 7을 사용하고 있습니다.

+0

'std :: make_unique'와 패밀리가 같은 한계를 가지고 있다면 : ( – Rakete1111

+0

집계 초기화는 항상 C++ 초기화 시스템의 가시가되었습니다. –

답변

1

생성자 추가 외에는이 문제에 대한 해결 방법이 없습니다. 당신이 언급 모두 과부하, 각각 [variant.ctor]19[variant.ctor]23에 대한 표준 위임이 :

효과는 : 인수 std​::​forward<Args>(args)...와 유형 T의 객체를 직접 비 목록 - 초기화 것처럼 포함 된 값으로 초기화합니다.

효과는 : 인수 il, std​::​forward<Args>(args)... 타이핑 T의 객체를 직접 비리스트 초기화하는 것과 포함 된 값으로 초기화.

당신은 항상 복사하거나 사용하여 객체를 이동할 수 있습니다 : 당신이 과잉 가고 싶은 경우에, 우리는 변환 연산자가 공장 유형 만들 수 있습니다

std::variant<x> v(std::in_place_type<x>, x{3}); 
// or more clear and does the same thing 
std::variant<x> v(x{3}); 
3

어쩌면 정확히 무엇을 요구하지 않겠습니까?하지만 형식 유추에 의존하지 않고 명시 적으로 개체를 구성하는 것은 어떨까요?

#include <variant> 

struct x { 
    int y; 
}; 

int main() { 
    std::variant<x> v(std::in_place_type<x>, x{3}); 
    return std::get<x>(v).y; 
} 
+0

사실 저는 이것에 만족할 것입니다!제목에 대한 나의 질문은 이것이 성취하는 생성자를 피하는 것에 관한 것입니다. 기술적으로는 약간의 이동이 포함되지만 간단한 경우 옵티마이 저가 오버 헤드없이이를 처리합니다. –

+0

실제로 클래스가 움직이는 생성자를 제공한다면 간단 할 것입니다. 명시 적으로 정의 된 생성자를 원하지 않으므로 암시 적으로 이동하는 생성자를 보장해야합니다 (또는 적어도 하나를 기본값으로 설정해야 함). – cbuchart

0

:

template <class... Args> 
struct list_init_from { 
    std::tuple<Args...> args; 

    template <class T> 
    operator T() { 
     return std::apply([](auto... args){ 
      return T{args...}; 
     }, args); 
    } 
}; 

template <class... Args> 
list_init_from(Args...) -> list_init_from<Args...>; 

을 어느 당신은 사용할 수 있습니다 :

std::variant<x> v(std::in_place_type<x>, list_init_from{3}); 

이것은 작동하지만 mu 적절한 전달, 변환 연산자에 대한 SFINAE, 그리고 변환을 허용 할 형식을 명시 적으로 지정하는 것은 독자에게 남겨진 연습 과제입니다.

관련 문제