C++17 구조 화 바 인 딩 의 실현
std::map
#include <iostream>
#include <map>
int main()
{
typedef std::map<int, int> Map;
Map map;
std::pair<Map::iterator, bool> result = map.insert(Map::value_type(1, 2));
if (result.second)
std::cout << "inserted successfully" << std::endl;
for (Map::iterator iter = map.begin(); iter != map.end(); ++iter)
std::cout << "[" << iter->first << ", " << iter->second << "]" << std::endl;
}
C++11 표준 라 이브 러 리 에 std::tie 를 추 가 했 습 니 다.약간의 인용 으로 std::tuple 을 구 조 했 습 니 다.std::tuple 대상 은 그 중의 인용 에 일일이 값 을 부여 할 수 있 습 니 다(이원 std::tuple 은 std::pair 구조 또는 할당 할 수 있 습 니 다).std::ignore 는 자리 차지 문자 로 위치 할당 이 무시 되 었 습 니 다.
#include <iostream>
#include <map>
#include <utility>
int main()
{
std::map<int, int> map;
bool inserted;
std::tie(std::ignore, inserted) = map.insert({1, 2});
if (inserted)
std::cout << "inserted successfully" << std::endl;
for (auto&& kv : map)
std::cout << "[" << kv.first << ", " << kv.second << "]" << std::endl;
}
그러나 이런 방법 은 아직 완벽 하지 않다.왜냐하면:
#include <iostream>
#include <map>
int main()
{
std::map<int, int> map;
auto&& [iter, inserted] = map.insert({1, 2});
if (inserted)
std::cout << "inserted successfully" << std::endl;
for (auto&& [key, value] : map)
std::cout << "[" << key << ", " << value << "]" << std::endl;
}
구조 화 바 인 딩 이라는 언어 특성 은 제안 단계 에서 분해 성명(decomposition declaration)이 라 고 불 렸 다가 구조 화 바 인 딩 으로 바 뀌 었 다.이 이름 이 강조 하고 자 하 는 것 은 구조 화 된 귀속 의 미 는 성명 이 아니 라 귀속 에 있다 는 것 이다.문법
구조 화 바 인 딩 은 세 가지 문법 이 있 습 니 다.
attr(optional) cv-auto ref-operator(optional) [ identifier-list ] = expression;
attr(optional) cv-auto ref-operator(optional) [ identifier-list ] { expression };
attr(optional) cv-auto ref-operator(optional) [ identifier-list ] ( expression );
그 중에서 attr(optional)는 선택 가능 한attributes이 고 cv-auto 는 const 또는 volatile 수식 이 있 을 수 있 는 auto 이 며,ref-operator(optional)는 선택 가능 한&또는&이 며,identifier-list 는 쉼표 로 구 분 된 식별 자 이 며,expression 은 하나의 표현 식 입 니 다.또한 initializer 를=expression,{expression}또는(expression)로 정의 합 니 다.다시 말 하면 위의 세 가지 문법 은 통 일 된 형식 attr(optional)cv-auto ref-operator(optional)[identifier-list]initializer 가 있 습 니 다.
전체 문 구 는 구조 화 된 바 인 딩 성명 으로 식별 자 는 구조 화 바 인 딩(structured bings)이 라 고도 부 르 지만 두 곳 의'binding'의 품사 가 다르다.
말 나 온 김 에 C++20 에서 volatile 의 많은 용법 이 폐기 되 었 다.
행위.
구조 화 바 인 딩 은 세 가지 행위 가 있 고 위의 세 가지 문법 과 대응 하 는 관계 가 없다.
첫 번 째 경우 expression 은 배열 이 고 identifier-list 의 길 이 는 배열 의 길이 와 같 아야 합 니 다.
두 번 째 상황,expression 의 유형 E,std::tuplesize
세 번 째 상황 에서 E 는 비 유 니 온 류 유형 으로 비 정적 데이터 구성원 을 연결 합 니 다.모든 비정 상 데이터 구성원 은 Public 접근 속성 이 어야 합 니 다.모두 E 에 있 거나 E 의 기본 클래스 에 있어 야 합 니 다(즉,여러 클래스 에 분산 되 어 서 는 안 됩 니 다).identifier-list 는 클래스 의 비정 상 데이터 구성원 의 성명 순서에 따라 연결 되 고 수량 이 같 습 니 다.
활용 단어 참조
구조 화 바 인 딩 은 순수 데이터 형식 을 처리 하 는 데 능 합 니 다.사용자 정의 형식 과 std:tuple 등 을 포함 하여 인 스 턴 스 의 모든 필드 에 변 수 를 할당 합 니 다.
#include <iostream>
struct Point
{
double x, y;
};
Point midpoint(const Point& p1, const Point& p2)
{
return { (p1.x + p2.x) / 2, (p1.y + p2.y) / 2 };
}
int main()
{
Point p1{ 1, 2 };
Point p2{ 3, 4 };
auto [x, y] = midpoint(p1, p2);
std::cout << "(" << x << ", " << y << ")" << std::endl;
}
다른 문법 사탕 과 함께 현대 C++코드 는 우아 할 수 있 습 니 다.
#include <iostream>
#include <map>
int main()
{
std::map<int, int> map;
if (auto&& [iter, inserted] = map.insert({ 1, 2 }); inserted)
std::cout << "inserted successfully" << std::endl;
for (auto&& [key, value] : map)
std::cout << "[" << key << ", " << value << "]" << std::endl;
}
구조 화 된 바 인 딩 이 클래스 원 그룹 유형 에 연 결 된 행 위 를 이용 하여 우 리 는 데이터 형식의 구조 화 바 인 딩 디 테 일 을 바 꿀 수 있 습 니 다.이 는 유형 전환,복사 여부 등 을 포함 합 니 다.
#include <iostream>
#include <string>
#include <utility>
class Transcript { /* ... */ };
class Student
{
public:
const char* name;
Transcript score;
std::string getName() const { return name; }
const Transcript& getScore() const { return score; }
template<std::size_t I>
decltype(auto) get() const
{
if constexpr (I == 0)
return getName();
else if constexpr (I == 1)
return getScore();
else
static_assert(I < 2);
}
};
namespace std
{
template<>
struct tuple_size<Student>
: std::integral_constant<std::size_t, 2> { };
template<>
struct tuple_element<0, Student> { using type = decltype(std::declval<Student>().getName()); };
template<>
struct tuple_element<1, Student> { using type = decltype(std::declval<Student>().getScore()); };
}
int main()
{
std::cout << std::boolalpha;
Student s{ "Jerry", {} };
const auto& [name, score] = s;
std::cout << name << std::endl;
std::cout << (&score == &s.score) << std::endl;
}
Student 는 데이터 형식 으로 두 필드 name 과 score 가 있 습 니 다.name 은 C 스타일 문자열 입 니 다.C 코드 에서 물 려 받 은 것 같 습 니 다.저 는 고객 이 C+스타일 의 std:string 을 사용 하 기 를 바 랍 니 다.score 는 Transcript 유형 으로 학생 들 의 성적 표를 나타 내 는데 이 구조 가 비교적 크 므 로 불필요 한 복사 가 없 도록 const 인용 을 전달 하고 싶 습 니 다.이 를 위해,나 는 세 가지 요 소 를 명확 하 게 썼 다:std:tuplesize、std::tuple_element 와 get.이런 메커니즘 은 구조 화 연결 에 매우 강 한 유연성 을 주 었 다.세부 사항
#include <iostream>
#include <utility>
#include <tuple>
int main()
{
std::pair pair{ 1, 2.0 };
int number = 3;
std::tuple<int&> tuple(number);
const auto& [i, f] = pair;
//i = 4; // error
const auto& [ri] = tuple;
ri = 5;
}
구조 화 바 인 딩 i 가 const auto&로 밝 혀 지면 해당 하 는 유형 이 int 라면 const int&가 아 닐 까요?i = 4;틀 렸 습 니 다.바로 그런 것 같 습 니 다.그러나 리=5 를 어떻게 해석 합 니까?합 법 적 인 건 가요?이 문 제 는 체계적으로 처음부터 이야기 해 야 한다.먼저 이름 e,E 를 그 유형 으로 도입 합 니 다.
그리고 세 가지 상황 으로 나 누 어 토론 한다.
이제 리 비 const 의 현상 을 설명 할 수 있 습 니 다.컴 파일 러 는 먼저 변수 const auto&e=tuple 을 만 들 었 습 니 다.E 는 const std::tuple
바 텀 을 위 한 C+프로 그래 밍 에 서 는 유 니 온 과 비트 필드(bit field)를 자주 사용 하고 구조 화 바 인 딩 은 이러한 데이터 구성원 을 지원 합 니 다.유 니 온 형식 구성원 이 있 으 면 이름 을 지어 야 합 니 다.바 인 딩 된 식별 자의 유형 은 이 유 니 온 형식의 왼쪽 값 입 니 다.이름 이 없 는 유 니 온 멤버 가 있다 면 이 종 류 는 구조 화 바 인 딩 에 사용 할 수 없습니다.
C++에는 비트 필드 의 포인터 와 참조 가 존재 하지 않 지만 구조 화 바 인 딩 은 비트 필드 의 왼쪽 값 을 가리 킬 수 있 습 니 다.
#include <iostream>
struct BitField
{
int f1 : 4;
int f2 : 4;
int f3 : 4;
};
int main()
{
BitField b{ 1, 2, 3 };
auto& [f1, f2, f3] = b;
f2 = 4;
auto print = [&] { std::cout << b.f1 << " " << b.f2 << " " << b.f3 << std::endl; };
print();
f2 = 21;
print();
}
프로그램 출력:1 4 3
1 5 3
f2 의 기능 은 비트 필드 의 인용 과 같이 원래 의 값 을 쓸 수 있 을 뿐만 아니 라 비트 필드 의 범 위 를 초과 하지 않 습 니 다.
get 의 이름 찾기,std:tuple 와 같은 문법 디 테 일 도 있 습 니 다.size
제한 하 다.
상기 코드 예 시 는 모든 유형의 구조 화 바 인 딩 응용 을 포함 하고 있 을 것 입 니 다.당신 이 상상 할 수 있 는 다른 문법 은 모두 틀 렸 습 니 다.포함 되 지만 이에 국한 되 지 않 습 니 다.
std::initializerlist
std::initializerlist
목록 으로 초기 화―auto[x,y,z]={1,"xyzzy"s,3.14159};
이것 은 세 개의 변 수 를 설명 하 는 것 과 같 지만 구조 화 된 바 인 딩 의 도 는 성명 이 아니 라 바 인 딩 에 있다.
설명 하지 않 고 직접 연결 합 니 다―[iter,success]=mymap.insert(value);
std::tie 를 사용 하 는 것 과 같 으 니 std::tie 를 계속 사용 하 세 요.또한[처음에는 attributes 와 헷 갈 릴 수 있 고 컴 파일 러 와 컴 파일 러 디자이너 에 게 부담 을 줄 수 있 습 니 다.
구조 화 바 인 딩 의 수식 자―auto[&x,const y,const&z]=f();
구조 화 된 바 인 딩 에서 벗 어 나 려 는 의도 이기 도 하 다.이러한 기능 이 필요 하거나 변 수 를 하나씩 정의 하거나 세 가지 요 소 를 수 동 으로 쓴다.
구조 화 바 인 딩 의 유형―SomeClast[x,y]=f()를 가리킨다.또는 auto[x,std::string y]=f();
첫 번 째 사용 가능 한 auto[x,y]=SomeClass{f()};대신두 번 째 는 이전 조항 과 같다.
구조 화 된 바 인 딩 을 무시 합 니 다.auto[x,std::ignore,z]=f();
컴 파 일 러 경 고 를 없 애 는 것 은 하나의 이유 이지 만 auto[x,y,z]=f();void)y;또한이것 은 또 일부 언어 문제 와 관련 이 있 으 니 P0144R 2 3.8 절 로 이동 하 십시오.
식별 자 끼 워 넣 기--std::tuple
한 줄 더 쓰 세 요.마찬가지 로 attributes 와 헷 갈 릴 수 있 습 니 다.
상기 문법 은 C++20 기준 에 포함 되 지 않 았 지만 앞으로 C+문법 확장 이 될 수 있 습 니 다.
뻗다
C++17 의 새로운 기능 은 고립 된 것 이 아니 라 구조 화 바 인 딩 과 관련 된 것 은:
클래스 템 플 릿 매개 변수 유도(class template argument deduction,CTAD)는 구조 함수 매개 변수 로 템 플 릿 매개 변 수 를 유도 합 니 다.
복사 생략(copy elision),NRV(named return value)의 최 적 화 를 보증한다.
constexpr if범 형 코드 를 간소화 하고 일부 SFINAE 를 제거한다.
초기 화 된 조건 부 분기 문:문법 사탕 은 코드 를 더욱 우아 하 게 한다.
C++17 구조 화 바 인 딩 의 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 C++17 구조 화 바 인 딩 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C 언어 구조 화 된 프로 그래 밍 을 깊이 이해 하 다.구 조 는 세 가지 가 있 습 니 다.순서 구조,선택 구조,순환 구조! 순서 구조:순서 구 조 는 가장 간단 하 다.문 제 를 해결 하 는 순서에 따라 해당 하 는 문 구 를 쓰 면 된다.그의 집행 순 서 는 위 에...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.