utility_piecewise_construct

utility_piecewise_construct (조각별 생성 태그)

std::piecewise_construct_tstd::pair나 그 외의 컨테이너 생성 과정에서 튜플 인자를 어떻게 해석할지를 구분해 주는 태그 타입이에요. 이 태그를 사용하면 각 튜플 인자가 요소 타입의 생성자 인자로 조각별(piecewise) 전달되어, 불필요한 임시 객체 생성을 피할 수 있어요. C++11부터 도입되었고, C++17부터는 piecewise_construct 상수가 inline 변수로 제공돼요.

출처: cppreference

본문

정의

<utility> 헤더에 다음과 같이 정의되어 있어요.

정의 (1) (2)
struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; (1) (C++11부터)
constexpr std::piecewise_construct_t piecewise_construct{}; (2) (C++11부터, C++17부터 inline)

std::piecewise_construct_t를 사용하지 않는 오버로드는 각 튜플 인자가 그대로 pair의 요소가 된다고 가정해요. 반면에 std::piecewise_construct_t를 사용하는 오버로드는 각 튜플 인자가 지정된 타입의 새 객체를 조각별로 생성하는 데 사용되고, 그 객체가 pair의 요소가 된다고 가정해요.

표준 라이브러리에서의 사용

다음 표준 라이브러리 타입과 함수들이 이 태그를 구분용 태그(disambiguation tag)로 사용해요.

타입/함수 설명
pair 두 값을 쌍으로 저장하는 이진 튜플 (클래스 템플릿)
uses_allocator_construction_args (C++20) 주어진 타입에 필요한 uses-allocator 생성 방식에 맞는 인자 목록을 준비하는 함수 템플릿
ranges::repeat_view, views::repeat (C++23) 같은 값을 반복 생성하여 만들어지는 시퀀스로 구성된 뷰 (클래스 템플릿, 커스터마이제이션 포인트 객체)

예제

#include <iostream>
#include <tuple>
#include <utility>

struct Foo
{
    Foo(std::tuple<int, float>)
    {
        std::cout << "Constructed a Foo from a tuple\n";
    }
 
    Foo(int, float)
    {
        std::cout << "Constructed a Foo from an int and a float\n";
    }
};

int main()
{
    std::tuple<int, float> t(1, 3.14);

    std::cout << "Creating p1...\n";
    std::pair<Foo, Foo> p1(t, t);

    std::cout << "Creating p2...\n";
    std::pair<Foo, Foo> p2(std::piecewise_construct, t, t);
}

출력:

Creating p1...
Constructed a Foo from a tuple
Constructed a Foo from a tuple
Creating p2...
Constructed a Foo from an int and a float
Constructed a Foo from an int and a float

예제에서 p1은 튜플을 그대로 Foo에 전달해서 Foo(std::tuple<int, float>) 생성자가 호출돼요. 반면 p2std::piecewise_construct를 사용해서 튜플의 요소들이 각각 분해되어 Foo(int, float) 생성자가 호출되는 것을 볼 수 있어요.

결함 보고 (Defect reports)

다음의 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.

DR 적용 대상 발표된 동작 올바른 동작
LWG 2510 C++11 기본 생성자가 explicit이 아니어서 모호함이 발생할 수 있었음 explicit으로 지정됨

같이 보기

(constructor) std::pair<T1,T2>의 새 pair를 생성하는 public 멤버 함수

더 알아보기 (Learn more)

cppreference