2016-07-29 6 views
4

:가에 튜플 내에서 유형을 교체 C++ 나는 다음을 수행 C++에서 템플릿을 사용하기 위해 노력하고있어 11

이 같은 기능이 있습니다이 기능 내부

template<typename... Args> 
void f1(const std::tuple<Args...>& t1); 

을, 나는 t1의 모든 요소가 타입 B의 객체를 생성해야하는 타입 A의 요소를 제외하고 같은 위치의 t2로 복사되는 또 다른 튜플 t2를 만들고 싶습니다.

그러나 생성자는 B은유형의 객체에 대한 참조를 취합니다.210 C& 유형의 두 번째 인수입니다. C의 인스턴스는 변환 전에 만들어지고 A 유형의 개체가 발생할 때마다 B의 생성자에 두 번째 인수로 전달되어야합니다. 단지 완전히 일반화 같은

뭔가 :

std::tuple<int, B, double, B> Convert(std::tuple<int, A, double, A> tpl, C& c) 
{ 
    return std::tuple<int, B, double, B>(
    std::get<0>(tpl), 
    B(std::get<1>(tpl), c), 
    std::get<2>(tpl), 
    B(std::get<3>(tpl), c), 
); 
} 
+2

좋아요, 그럼 무슨 문제에 직면 했습니까? SO는 무료 아웃소싱 장소가 아닙니다. –

+0

나는 아주 멀리 가지 않았다; 내 코드의 다른 위치에서 튜플을 조작하는 템플릿 코드를 작성해야했습니다. 예를 들어 인수와 같은 유형의 필드를 포함하는 튜플에 일련의 인수를 취하는 함수를 적용하는 것과 반대입니다. 인자를 하나의 튜플에 넣는 것은 쉽다) 그래서 나는 튜플 t1을 받았다고 가정하거나 일련의 주장을 가지고 있다고 가정하면서 위의 것을 할 수있는 방법을 찾으려고 노력하지만 나는 아무데도 가지 않는다. – sunmat

+0

어리석은'C '가 없다면 메타 프로그래밍이 비교적 쉬울 것입니다 (물론 C++ 14에 액세스 할 수 있다고 가정 할 때). 그러나 그 제한이 있기 때문에, 당신이 각 값을 구성하기 위해 사용하는 식은 이제 그 값의 유형에 따라 * 다른 *이기 때문에 매우 어렵게됩니다. 표현식을 정규화하는 방법을 찾아야 만합니다. 표현식을 정규화하는 방법은 '튜플 (tuple)'을 만들 필요가 있습니다. –

답변

3

참고 : 새로운 질문은 더 복잡한 것을 요청합니다. 도움이 될 사람들을 위해이 대답을 남겨주세요.

템플릿 조건문 및 서식 파일 팩 확장의 힘 :이 솔루션은 대부분 때문에 std::make_index_sequence을의, C++ (14)를 필요로

#include<functional> 
#include<tuple> 
#include<cassert> 

struct A {}; 
struct C {}; 
struct B { B(const A &, C &) {} }; 

template<typename T> 
T g(const T &t, C &) { return t; } 

B g(const A &a, C &c) { 
    return B{a, c}; 
} 

template<std::size_t... I, typename... Args> 
void f(const std::tuple<Args...> &tup,std::index_sequence<I...>) { 
    C c; 
    auto val = std::make_tuple(g(std::get<I>(tup), c)...); 
    assert((std::is_same<std::tuple<C, B, C>, decltype(val)>::value)); 
} 

template<typename... Args> 
void f(const std::tuple<Args...> &tup) { 
    f(tup, std::make_index_sequence<sizeof...(Args)>()); 
} 

int main() { 
    auto tup = std::make_tuple(C{}, A{}, C{}); 
    f(tup); 
} 

참고 :이 문제를 해결할 생각

template<typename... Args> 
void f1(const std::tuple<Args...>& t1) { 
    std::tuple<typename std::conditional< 
     std::is_same<A, Args>::value, B, Args>::type...> t2(t1); 
    // Both Args are expanded in parallel, resulting in the same types 
    // Do things with t2 
} 
+0

고마워, 그 시작이다. 그러나 나는 B의 생성자가 const A와 다른 인수를 취했다는 것을 잊었다. 두 번째 인수를 생성자에 전달하려면 어떻게해야합니까? – sunmat

+0

내 질문을 편집했습니다. 감사. – sunmat

+0

@sunmat : 그건 좀 더 복잡하고 복잡한 질문입니다. 어쨌든 끝낼 수 있습니다. – Deduplicator

1

std::index_sequence.
필요할 경우 온라인으로 C++ 11 구현을 찾을 수 있습니다.

+0

적절한 매핑 (로컬 클래스에서 정의 됨)을 사용하여 단순히'f'에 의해 호출되는 별도의 함수로 매핑을 분리 할 수 ​​있습니다. – Deduplicator

+0

@Deduplicator 그래, 최소한의 작동 예제입니다. 나는 실제 세계가 무엇인지 모르는 코드를 구조화하는 방법을 모른다. – skypjack