std::get<N>
(std::tuple)
메쏘드를 직접 만들려고 시도한 후에 컴파일러에 의해 어떻게 구현되는지 잘 모르겠습니다. 나는 std::tuple
이 같은 생성자가std ::는 어떻게 작동합니까?
tuple(Args&&... args);
알고 있지만 정확히 args...
가 할당된다? 나는 이것들이 어떻게 접근하는지 알기 위해서 유용하다고 생각한다 ...
std::get<N>
(std::tuple)
메쏘드를 직접 만들려고 시도한 후에 컴파일러에 의해 어떻게 구현되는지 잘 모르겠습니다. 나는 std::tuple
이 같은 생성자가std ::는 어떻게 작동합니까?
tuple(Args&&... args);
알고 있지만 정확히 args...
가 할당된다? 나는 이것들이 어떻게 접근하는지 알기 위해서 유용하다고 생각한다 ...
다음은 tuple
과 같은 클래스의 조잡한 장난감 구현이다.
첫째, 일부 메타 프로그래밍 상용구는 정수 시퀀스 나타내는데 :
template<int...> struct seq {};
template<int max, int... s> struct make_seq:make_seq< max-1, max-1, s... > {};
template<int... s> struct make_seq<0, s...> {
typedef seq<s...> type;
};
template<int max> using MakeSeq = typename make_seq<max>::type;
다음에, 실제 데이터를 저장하는 태그 클래스 :
template<int x, typename Arg>
struct foo_storage {
Arg data;
};
이 태그 기술은 일반적인 패턴마다이며 우리는 컴파일 타임에 어떤 태그 (이 경우에는 정수)와 데이터를 연관시키고 자한다. 태그 (여기 int
)는 일반적으로 저장소의 어느 곳에서나 사용되지 않고 저장소에 태그하는 데 사용됩니다.
foo_helper
은 일련의 인수를 묶음 foo_storage
에 압축 해제 한 다음 선형 형식으로 상속합니다. 이것은 매우 일반적인 패턴이다 -이 많이하고 있다면, 당신은 당신을 위해 이렇게 메타 프로그래밍 도구를 만들어 결국 :
template<typename Seq, typename... Args>
struct foo_helper {};
template<int s0, int... s, typename A0, typename... Args>
struct foo_helper<seq<s0, s...>, A0, Args...>:
foo_storage<s0, A0>,
foo_helper<seq<s...>, Args...>
{};
내 원유 tuple
유형, foo
는, 인덱스의 순서의 패키지를 만듭니다 args를 가져 와서 위의 도우미에게 전달합니다. 이 get
을 구현하는 데 필요한되지 않기 때문에,
template<typename... Args>
struct foo: foo_helper< MakeSeq<sizeof...(Args)>, Args... > {};
내가 foo
의 몸에서 모든 것을 제거 : 도우미는 태그 데이터 잡고 부모 클래스의 무리를 만듭니다. 우리는 저장 유형 (안 튜플 타입)을 가지고, 그리고 foo_storage<n, T>
의 우리가 가고있는 명시 적 template
인수 N
들의 차이는 액세스 할 :
get
은 아주 간단합니다. 우리는 무거운 작업을 수행 할 C++ langauge의 과부하 메커니즘을 사용하는
template<int N, typename T>
T& get(foo_storage<N, T>& f)
{ return f.data; }
template<int N, typename T>
T const& get(foo_storage<N, T> const& f)
{ return f.data; }
: 이제 우리는 스토리지 유형을 가지고, 우리는 단순히 데이터 필드를 반환합니다. 클래스 인스턴스가있는 함수를 호출 할 때 각 부모 클래스가 해당 인스턴스로 이동하여 해당 인스턴스 중 하나라도 일치시킬 수 있는지 확인합니다. N
을 수정하면 올바른 인수 인 부모 클래스가 하나만 있으므로 부모 클래스 (따라서 T
)가 자동으로 추론됩니다.
#include <iostream>
int main() {
foo<int, double> f;
get<0>(f) = 7;
get<1>(f) = 3.14;
std::cout << get<0>(f) << "," << get<1>(f) << "\n";
}
당신이 부스트 :: get''쳐다 보면서'부스트 : tuple' 있습니다
그리고 마지막으로, 몇 가지 기본적인 테스트 코드
? 'std :: get'이 구현 된 헤더 파일은 어떻습니까? * 읽기 쉽지는 않지만 대개 C++ 에서처럼 구현됩니다. (이 표준은 표준 라이브러리가 C++로 구현 될 것을 요구하지 않습니다) – Yakk