가변 템플릿에 대한 변수 목록 생성

Makogan

C ++ 17 이상에서는 구조를 다음과 같이 변수로 분해 할 수 있습니다.

struct MyStruct
{
    int f1;
    int f2;
    int f3;
};
auto& [f1, f2, f3] = my_struct;

나는 가변 팩 기능에서 그렇게하려고합니다.

template <class ... T, std::size_t...I>
constexpr std::size_t CountFields(std::index_sequence<I...>)
{
    T t;
    auto& [] = t;
    return 0;
}

그러나 변수를 얻기 위해 대괄호 사이의 공간을 채우는 방법을 완전히 모르겠습니다. 최종 목표는 이러한 변수를 사용하여 튜플을 만드는 것입니다 (즉, 튜플 함수에 대한 일반 구조체를 만들려고합니다). 내가 찾은 가장 가까운 것은 this : struct to / from std :: tuple conversion .

하지만 몇 가지 이유로 BOOST를 피해야합니다.

RedFog

슬프게도 구조화 된 바인딩에서 매개 변수 팩을 사용할 방법이 없다는 것은 분명합니다. 반면에 구조화 된 바인딩 없이는 데이터 멤버를 바인딩 할 수 없습니다.

그러나 데이터 멤버의 양을 제공하면 기존 방식으로 바인딩 할 수 있습니다.

template<size_t>
struct structToTupleHelper;

template<>
struct structToTupleHelper<0>; // ISO C++17 does not allow a decomposition group to be empty.

template<>
struct structToTupleHelper<1>{
    template<typename X, size_t... Is>
    static auto convert(X&& x, std::index_sequence<Is...>){
        auto&& [a1] = std::forward<X>(x); // bound variables are always thought as lvalue.
        auto temp = std::forward_as_tuple(a1);
        return std::forward_as_tuple(std::get<Is>(temp)...);
    }
};

template<>
struct structToTupleHelper<2>{
    template<typename X, size_t... Is>
    static auto convert(X&& x, std::index_sequence<Is...>){
        auto&& [a1, a2] = std::forward<X>(x); // bound variables are always thought as lvalue.
        auto temp = std::forward_as_tuple(a1, a2);
        return std::forward_as_tuple(std::get<Is>(temp)...);
    }
};

// ...
// maybe 16 is enough?

template<typename X, size_t... Is>
auto structToTuple(X&& x, std::index_sequence<Is...> _1){
    return structToTupleHelper<sizeof...(Is)>::convert(std::forward<X>(x), _1);
}

template<size_t N, typename X, size_t... Is>
auto structToTuple(X&& x, std::index_sequence<Is...> _1){
    return structToTupleHelper<N>::convert(std::forward<X>(x), _1);
}

template<size_t N, typename X>
auto structToTuple(X&& x){
    return structToTupleHelper<N>::convert(std::forward<X>(x), std::make_index_sequence<N>());
}

다음과 같이 사용할 수 있습니다.

int ii;
struct A{
    int& a;
} a{ii};
struct B{
    int a;
} b;

auto t1 = structToTuple<1>(A{ii}); // tuple<int&>, valid.
auto t2 = structToTuple<1>(a);     // tuple<int&>, valid.
auto t3 = structToTuple<1>(B{});   // tuple<int&>, invalid: a lvalue reference is bound to a temporary object.
auto t4 = structToTuple<1>(b);     // tuple<int&>, valid.
somefunc(structToTuple<1>(B{})); // valid. the temporary object is alive inside 'somefunc'.
structToTuple<1>(A{ii}) = std::tuple(1); // valid. assign 1 to 'ii'.
structToTuple<1>(a) = std::tuple(1);     // valid. assign 1 to 'ii'.
structToTuple<1>(B{}) = std::tuple(1);   // unexpected. assign 1 to the member of a temporary object.
structToTuple<1>(b) = std::tuple(1);     // valid. assign 1 to 'b.a'.

// struct C{
//     int a : 8;
// } c;
// auto t5 = structToTuple<1>(C{}); // invalid: bitfields can not be treated as non-const lvalue reference
// auto t6 = structToTuple<1>(c);   // invalid: bitfields can not be treated as non-const lvalue reference

전문화하는 것이 번거 롭다고 생각할 수도 있습니다. 다행스럽게도 매크로를 사용하여 단순화 할 수 있습니다. (BOOST가 항상하는 일입니다.)

#define XXX_CONCAT_HELPER(a, b) a##b
#define XXX_CONCAT(a, b) XXX_CONCAT_HELPER(a, b)

#define XXX_COMMA ,
#define XXX_COMMA_FUNC(a) ,
#define XXX_EMPTY
#define XXX_EMPTY_FUNC(a)

#define XXX_REPEAT_0(func, join)
#define XXX_REPEAT_1(func, join) func(1)
#define XXX_REPEAT_2(func, join) XXX_REPEAT_1(func,join) join(2) func(2)
// ...
#define XXX_REPEAT_256(func, join) XXX_REPEAT_255(func,join) join(256) func(256)

#define XXX_REPEAT(func, times, join) XXX_CONCAT(XXX_REPEAT_,times)(func,join)

// macro is not allowed to be recursive, so we need another repeat function.
#define XXX_ALIAS_REPEAT_0(func, join)
#define XXX_ALIAS_REPEAT_1(func, join) func(1)
#define XXX_ALIAS_REPEAT_2(func, join) XXX_ALIAS_REPEAT_1(func,join) join(2) func(2)
// ...
#define XXX_ALIAS_REPEAT_256(func, join) XXX_ALIAS_REPEAT_255(func,join) join(256) func(256)

#define XXX_ALIAS_REPEAT(func, times, join) XXX_CONCAT(XXX_ALIAS_REPEAT_,times)(func,join)

#define STRUCT_TO_TUPLE_TOKEN_FUNC(n) XXX_CONCAT(a,n)

#define STRUCT_TO_TUPLE_FUNC(n) \
template<> \
struct structToTupleHelper<n>{ \
    template<typename X, size_t... Is> \
    static auto convert(X&& x, std::index_sequence<Is...>){ \
        auto&& [XXX_REPEAT(STRUCT_TO_TUPLE_TOKEN_FUNC,n,XXX_COMMA_FUNC)] = std::forward<X>(x); \
        auto temp = std::forward_as_tuple(XXX_REPEAT(STRUCT_TO_TUPLE_TOKEN_FUNC,n,XXX_COMMA_FUNC)); \
        return std::forward_as_tuple(std::get<Is>(temp)...); \
    } \
}; \


XXX_ALIAS_REPEAT(STRUCT_TO_TUPLE_FUNC,128,XXX_EMPTY_FUNC)

#undef STRUCT_TO_TUPLE_TOKEN_FUNC
#undef STRUCT_TO_TUPLE_FUNC

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

복잡한 목록 변수에서 템플릿 사용

분류에서Dev

템플릿 매개 변수에 대한 템플릿 전문화

분류에서Dev

템플릿 템플릿 매개 변수에 대한 추론 가이드

분류에서Dev

특성에 대한 추악한 매개 변수 목록 개선

분류에서Dev

typename에 대한 가변 템플릿 풀기 인수

분류에서Dev

std :: function에 대한 가변 템플릿 인수

분류에서Dev

SASS : 클래스 목록에서 변수 목록 생성 (반대의 경우도 가능)

분류에서Dev

가변 템플릿을 통한 C ++ 11 생성자 상속

분류에서Dev

여러 유형의 함수에 대한 매개 변수로 함수 포인터를받는 함수에 대한 템플릿 함수 생성

분류에서Dev

봄 부팅 구성의 목록에 대한 환경 변수

분류에서Dev

각 가변 템플릿 인수에 대한 함수를 호출하고 결과를 생성자 인수로 전달

분류에서Dev

생성자 내부의 클래스 이름에 대한 템플릿 매개 변수 추가 및 생략의 차이점

분류에서Dev

가변 및 템플릿 템플릿 매개 변수 및 트리 노드 클래스에 대한 부분 사양

분류에서Dev

변수에 대한 루프 목록 Python

분류에서Dev

매개 변수 확장을 사용하여`mkdir -p`에 대한 인수 목록 생성

분류에서Dev

선형 계층에 대한 C ++ 가변 템플릿 매개 변수

분류에서Dev

컴파일러가 가변 템플릿에 대한 템플릿 인수를 추론 할 수 없습니다.

분류에서Dev

두 목록에서 Ansible YAML 변수를 처리하기위한 Jinja2 중첩 루프 템플릿

분류에서Dev

Django, 템플릿에서 변수 생성 및 값 할당

분류에서Dev

생성자에 지정된 템플릿 매개 변수

분류에서Dev

C ++에서 가변 템플릿 초기화를위한 일치하는 생성자가 없습니다.

분류에서Dev

템플릿 가상 클래스 C ++에 대한 참조 생성

분류에서Dev

템플릿 클래스의 템플릿 유형에 대한 매개 변수를 추가 할 수 있습니까?

분류에서Dev

conftest.py의 cmdline 옵션에서 생성 된 목록에 대한 테스트의 Pytest 매개 변수화

분류에서Dev

다른 특성에 대한 템플릿 매개 변수로 특성 인스턴스

분류에서Dev

동일한 유형의 가변 템플릿 인수가있는 생성자가 컴파일되지 않음

분류에서Dev

Angular 7에서 템플릿 html 속성 * key *에 대한 변수를 사용하는 방법이 있습니까?

분류에서Dev

Coq : 가변 인수 목록에 대한 Ltac 정의?

분류에서Dev

systemd 템플릿에 대한 udev 규칙 매개 변수

Related 관련 기사

  1. 1

    복잡한 목록 변수에서 템플릿 사용

  2. 2

    템플릿 매개 변수에 대한 템플릿 전문화

  3. 3

    템플릿 템플릿 매개 변수에 대한 추론 가이드

  4. 4

    특성에 대한 추악한 매개 변수 목록 개선

  5. 5

    typename에 대한 가변 템플릿 풀기 인수

  6. 6

    std :: function에 대한 가변 템플릿 인수

  7. 7

    SASS : 클래스 목록에서 변수 목록 생성 (반대의 경우도 가능)

  8. 8

    가변 템플릿을 통한 C ++ 11 생성자 상속

  9. 9

    여러 유형의 함수에 대한 매개 변수로 함수 포인터를받는 함수에 대한 템플릿 함수 생성

  10. 10

    봄 부팅 구성의 목록에 대한 환경 변수

  11. 11

    각 가변 템플릿 인수에 대한 함수를 호출하고 결과를 생성자 인수로 전달

  12. 12

    생성자 내부의 클래스 이름에 대한 템플릿 매개 변수 추가 및 생략의 차이점

  13. 13

    가변 및 템플릿 템플릿 매개 변수 및 트리 노드 클래스에 대한 부분 사양

  14. 14

    변수에 대한 루프 목록 Python

  15. 15

    매개 변수 확장을 사용하여`mkdir -p`에 대한 인수 목록 생성

  16. 16

    선형 계층에 대한 C ++ 가변 템플릿 매개 변수

  17. 17

    컴파일러가 가변 템플릿에 대한 템플릿 인수를 추론 할 수 없습니다.

  18. 18

    두 목록에서 Ansible YAML 변수를 처리하기위한 Jinja2 중첩 루프 템플릿

  19. 19

    Django, 템플릿에서 변수 생성 및 값 할당

  20. 20

    생성자에 지정된 템플릿 매개 변수

  21. 21

    C ++에서 가변 템플릿 초기화를위한 일치하는 생성자가 없습니다.

  22. 22

    템플릿 가상 클래스 C ++에 대한 참조 생성

  23. 23

    템플릿 클래스의 템플릿 유형에 대한 매개 변수를 추가 할 수 있습니까?

  24. 24

    conftest.py의 cmdline 옵션에서 생성 된 목록에 대한 테스트의 Pytest 매개 변수화

  25. 25

    다른 특성에 대한 템플릿 매개 변수로 특성 인스턴스

  26. 26

    동일한 유형의 가변 템플릿 인수가있는 생성자가 컴파일되지 않음

  27. 27

    Angular 7에서 템플릿 html 속성 * key *에 대한 변수를 사용하는 방법이 있습니까?

  28. 28

    Coq : 가변 인수 목록에 대한 Ltac 정의?

  29. 29

    systemd 템플릿에 대한 udev 규칙 매개 변수

뜨겁다태그

보관