Notice
Recent Posts
Recent Comments
Link
- 책_곽용재님 홈페이지
- 책_노란북 - 책 가격비교
- 책_김재우-SICP번역
- 플밍_쏘쓰포지
- 플밍_CodingHorror ?
- 플밍_상킴
- 플밍_김민장님
- GPGStudy
- 플밍_미친감자님
- 플밍_jz
- 플밍_샤방샤방님
- 플밍_글쓰는프로그래머2
- 플밍_키보드후킹
- 사람_재혁
- 사람_kernel0
- 사람_박PD
- 사람_경석형
- 사람_nemo
- 사람_kikiwaka
- 사람_Junios
- 사람_harry
- 사람_어떤 개발자의 금서목록..
- 사람_모기소리
- 사람_낙타한마리
- 사람_redkuma
- 사람_영원의끝
- 사람_민식형
- 도스박스 다음카페
- 플레이웨어즈 - 게임하드웨어벤치마크
- http://puwazaza.com/
- David harvey의 Reading Marx's c…
- 씨네21
- 한겨레_임경선의 이기적인 상담실
- 본격2차대전만화 - 굽시니스트
- 영화_정성일 글모음 페이지
- 영화_영화속이데올로기파악하기
- 음식_생선회
- 죽력고
- 사람_한밀
- 플밍_수까락
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 게임
- 소비자고발
- template
- 인문학
- 태그가 아깝다
- 삼국지6
- 진중권
- 유시민
- 건강
- modernc++
- 단상
- 프로그래밍
- 김두식
- 진삼국무쌍5
- Programming
- 일리아스
- programming challenges
- stl
- 강유원
- 고전강의
- 노무현
- 정성일
- BSP
- 책
- 고등학교 사회공부
- 영화
- c++
- 정신분석
- 삼국지
- 유머
Archives
- Today
- Total
01-07 02:28
lancelot.com
가변인자 template 을 이용한 생성자, tag dispatching 을 이용한 생성자 선택 본문
- 가변인자 template을 이용한 생성자
#include<iostream>
#include<string>
#include<type_traits>
class Point
{
int x{ 0 };
int y{ 0 };
public :
Point() = default;
Point(int x, int y) : x(x), y(y) {}
};
template<typename T1, typename T2, bool = std::is_empty_v<T1> > struct compressed_pair;
template<typename T1, typename T2> struct compressed_pair < T1, T2, false>
{
T1 first;
T2 second;
T1& getFirst() { return first; }
T2& getSecond() { return second; }
const T1& getFirst() const { return first; }
const T2& getSecond() const { return second; }
template<typename A1, typename ... A2>
compressed_pair(A1&& arg1, A2&& ... arg2) : first(std::forward<A1>(arg1)), second(std::forward<A2>(arg2)...) {}
};
int main()
{
compressed_pair<int, Point> p1(1, Point(0,0)); // 기본 생성자
compressed_pair<int, Point> p2(1, 0, 0); // 가변인자 템플릿을 사용한 생성자
}
- tag dispatching을 이용한 생성자 선택
#include<iostream>
#include<string>
#include<type_traits>
class Point
{
int x{ 0 };
int y{ 0 };
public :
Point() = default;
Point(int x, int y) : x(x), y(y) {}
};
class one_and_variadic_arg_t {};
class zero_and_variadic_arg_t {};
template<typename T1, typename T2, bool = std::is_empty_v<T1> > struct compressed_pair;
template<typename T1, typename T2> struct compressed_pair < T1, T2, false>
{
T1 first;
T2 second;
T1& getFirst() { return first; }
T2& getSecond() { return second; }
const T1& getFirst() const { return first; }
const T2& getSecond() const { return second; }
template<typename A1, typename ... A2>
compressed_pair(one_and_variadic_arg_t, A1&& arg1, A2&& ... arg2) : first(std::forward<A1>(arg1)), second(std::forward<A2>(arg2)... ) {}
template<typename ... A2>
compressed_pair(zero_and_variadic_arg_t, A2&& ... arg2) : first(), second(std::forward<A2>(arg2)... ) {}
};
int main()
{
compressed_pair<int, Point> p1(one_and_variadic_arg_t{}, 1, Point(0, 0));
compressed_pair<int, Point> p2(one_and_variadic_arg_t{}, 1, 0, 0);
compressed_pair<int, Point> p3(zero_and_variadic_arg_t{}, 0, 0);
}
- constexpr : 컴파일시간에 결정가능하다면 그렇게 할 수 있게
- noexcept 의 조건 설정
#include<iostream>
#include<string>
#include<type_traits>
class Empty { };
struct one_and_variadic_arg_t { explicit one_and_variadic_arg_t() = default; };
struct zero_and_variadic_arg_t { explicit zero_and_variadic_arg_t() = default; };
template<typename T1, typename T2, bool = std::is_empty_v<T1> && !std::is_final_v<T1> > struct compressed_pair;
template<typename T1, typename T2> struct compressed_pair < T1, T2, false>
{
T1 first;
T2 second;
constexpr T1& getFirst() noexcept { return first; } // 컴파일 시간에 결정되도록
constexpr T2& getSecond() noexcept { return second; }
constexpr const T1& getFirst() const noexcept { return first; }
constexpr const T2& getSecond() const noexcept { return second; }
template<typename A1, typename ... A2>
constexpr compressed_pair(one_and_variadic_arg_t, A1&& arg1, A2&& ... arg2)
noexcept ( // noexcept의 조건 - 멤버의 생성자가 예외를 던지지않음
std::conjunction_v< std::is_nothrow_constructible<T1, A1>, std::is_nothrow_constructible<T2, A2...> >)
: first(std::forward<A1>(arg1)), second(std::forward<A2>(arg2)...) {}
template<typename ... A2>
constexpr compressed_pair(zero_and_variadic_arg_t, A2&& ... arg2) noexcept(
std::conjunction_v< std::is_nothrow_default_constructible<T1>, std::is_nothrow_constructible<T2, A2...> >)
: first(), second(std::forward<A2>(arg2)...) {}
};
// T1 이 empty 인 경우
template<typename T1, typename T2> struct compressed_pair < T1, T2, true> : public T1
{
T2 second;
constexpr T1& getFirst() noexcept { return *this; }
constexpr T2& getSecond() noexcept { return second; }
constexpr const T1& getFirst() const noexcept { return *this; }
constexpr const T2& getSecond() const noexcept { return second; }
template<typename A1, typename ... A2>
constexpr compressed_pair(one_and_variadic_arg_t, A1&& arg1, A2&& ... arg2)
noexcept (
std::conjunction_v< std::is_nothrow_constructible<T1, A1>, std::is_nothrow_constructible<T2, A2...> >)
: T1(std::forward<A1>(arg1)), second(std::forward<A2>(arg2)...) {}
template<typename ... A2>
constexpr compressed_pair(zero_and_variadic_arg_t, A2&& ... arg2) noexcept(
std::conjunction_v< std::is_nothrow_default_constructible<T1>, std::is_nothrow_constructible<T2, A2...> >)
: T1(), second(std::forward<A2>(arg2)...) {}
};
int main()
{
compressed_pair<int, int> cp1 ( one_and_variadic_arg_t{}, 1, 1);
compressed_pair<Empty, int> cp2 ( zero_and_variadic_arg_t{}, 1);
compressed_pair<Empty, int> cp3 ( zero_and_variadic_arg_t{});
std::cout << sizeof(cp1) << std::endl;
std::cout << sizeof(cp2) << std::endl;
}