C++

[C++17] 템플릿 인자를 생략한다? Deduction Guide

카루-R 2020. 3. 21. 15:05
반응형

1부터 10까지 저장하는 배열을 하나 생성해보죠.

int nArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

아니면 간단히

int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// C++11에는 중괄호를 두 번씩 써야 함: {{1, 2, 3 ... 10}}
std::array<int, 10> array{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

그런데, 자료형이 모두 int이고 그 개수가 10개라는건 뻔히 알 수 있습니다.

굳이 <int, 10>이 필요할까요?

그래서 C++17에서는 Deduction Guide라는 것을 사용합니다.

만약에, 우리가 어떤 (템플릿) 클래스를 만드는데, 생성자의 매개변수가 문자열일때,

char*가 아닌 std::string으로 받는 방법이 있습니다.

#include <iostream>
#include <type_traits> // std::is_same_v (C++17 이상)
using namespace std;

template<typename T>
class container {
public:
    container(T t) : elem{t} {}
    T elem;
};
// 주목. const char* 형식의 매개변수는 T에 string을 넘긴다
container(const char*) -> container<string>;

int main() {
    container cnt{"CONTAINER"};
    
    // 이 부분을 주목하세요.
    return static_cast<int>(
        // decltype(cnt.elem)은 cnt.elem의 타입을 가져옴, 그것을 string과 비교
        !is_same_v<decltype(cnt.elem), string>);
        // 같으면 true, 그걸 반전시키니 false, int로 캐스팅 = 0 = 정상종료.
}

결과는 0이 나옵니다. 무슨 결과? main()의 반환값이요.

container(const char*) -> container; 이 부분을 주석처리하면 1이 반환됩니다.

T는 const char*인데도 string이 들어오는것입니다.

이게 배열하고 뭔 상관이냐? 다음 코드를 보시죠. (C++20이상에서만 동작합니다.)

#include <array>
#include <iostream>

int main() {
    for (std::array a{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int n : a)
        std::cout << n << ' ';
}

std::array이 아니라 그냥 std::array입니다.

이 외에도 basic_string, tuple(일부) 등등이 가능합니다.

또다른 예시로 std::pair를 보여드리겠습니다. (C++17이상에서만 가능합니다)

#include <iostream>
using namespace std;

int main() {
    pair p{2467368, "esdjkvhwjhjl"};
    auto&& [n, s] = p; // 구조체 바인딩
    n = 3; // n은 int타입
    s = "3"; // s는 string타입
    cout << p.first << p.second;
}

대입부분을 한줄로 묶으려면 이렇게 하면 됩니다.

// Go 언어에서는: n, s = 3, "3"
// C#(7+)에서는: (n, s) = (3, "3");
// C++에서는:
std::tie(n, s) = std::tuple{3, "3"}; // tuple의 템플릿 인자를 생략했습니다.

위 예제코드는 pair에 템플릿 인자를 명시하지 않았음에도 불구하고 잘 작동합니다.

auto &[n, s] = p는 구조체 바인딩이란 기능인데, p를 풀어서 첫번째 필드는 n에, 두번째 필드는 s에

대입합니다. 연결시킵니다. 복사가 아니라 레퍼런스입니다!

C++17의 Deduction Guide, 편리하고 간단한 소스코드의 밑거름이 되기를 희망합니다.

템플릿 인자여, 이젠 안녕!

반응형