[2026] C++ tuple detailed Complete Guide | Tuple guide

[2026] C++ tuple detailed Complete Guide | Tuple guide

이 글의 핵심

C++ tuple: basic usage, structured binding (C++17), principles, code, and practical applications.

Entering

std::tuple is a type introduced in C++11 that stores multiple values ​​together. This is useful when returning multiple values ​​from a function or temporarily grouping multiple values ​​together. 다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
int main() {
    // Creating a tuple: Bundles values ​​of multiple types into one
    // <int, double, std::string>: Types to store (order is important)
    std::tuple<int, double, std::string> t{42, 3.14, "hello"};
    
    // Access: std::get<index>(tuple)
    // Index must be a compile-time constant (template argument)
    int x = std::get<0>(t);        // first element (int)
    double y = std::get<1>(t);     // second element (double)
    std::string z = std::get<2>(t); // third element (string)
    
    std::cout << x << ", " << y << ", " << z << std::endl;
    
    return 0;
}

output of power:

42, 3.14, hello

1. Basic use

Create

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
int main() {
    // Method 1: Create directly (specify type)
    std::tuple<int, double> t1{42, 3.14};
    
    // Method 2: make_tuple (automatic type inference)
    // "hello" is inferred as const char*
    auto t2 = std::make_tuple(42, 3.14, "hello");
    
    // Method 3: C++17 CTAD (Class Template Argument Deduction)
    // Inferring type from constructor arguments without specifying type
    // std::string("world"): explicitly specify string type
    std::tuple t3{42, 3.14, std::string("world")};  // C++17
    
    // Size: Check the number of elements in a tuple at compile time
    // std::tuple_size_v: Returns the number of elements in a tuple (C++17)
    // decltype(t1): Extract type of t1
    constexpr size_t size1 = std::tuple_size_v<decltype(t1)>;  // 2
    constexpr size_t size2 = std::tuple_size_v<decltype(t2)>;  // 3
    
std::cout << "t1 size: " << size1 << std::endl;
std::cout << "t2 size: " << size2 << std::endl;
    
    return 0;
}

output of power:

t1 size: 2
t2 size: 3

Access

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
int main() {
    std::tuple<int, double, std::string> t{42, 3.14, "hello"};
    
    // access by index
    int x = std::get<0>(t);
    double y = std::get<1>(t);
    std::string z = std::get<2>(t);
    
    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
    std::cout << "z: " << z << std::endl;
    
    // Access by type (when the type is unique)
    int x2 = std::get<int>(t);
    double y2 = std::get<double>(t);
    std::string z2 = std::get<std::string>(t);
    
    std::cout << "x2: " << x2 << std::endl;
    
    return 0;
}

output of power: 다음은 간단한 code 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

x: 42
y: 3.14
z: hello
x2: 42

2. structured binding (C++17)

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
std::tuple<int, std::string, bool> parseUser(const std::string& data) {
    // Parsing logic (example)
    int id = 123;
    std::string name = "Alice";
    bool active = true;
    
    // Return tuple: Return multiple values ​​at once
    // {id, name, active}: Create tuple with curly brace initialization
    return {id, name, active};
}
int main() {
    // C++17 structured binding: decomposing tuple into individual variables
    // auto: Automatic type inference (tuple<int, string, bool>)
    // [id, name, active]: Variable name to receive each element
    // Elements of tuple are assigned in order
    auto [id, name, active] = parseUser("data");
    
    std::cout << "ID: " << id << std::endl;
std::cout << "name: " << name << std::endl;
std::cout << "active: " << (active ? "true" : "false") << std::endl;
    
    return 0;
}

output of power:

ID: 123
Name: Alice
active: true

3. tie

Unpack to existing variable

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
std::tuple<int, double> getValues() {
    return {42, 3.14};
}
int main() {
    // Declare an existing variable (uninitialized)
    int x;
    double y;
    
    // std::tie: Create a tuple by binding existing variables by reference.
    // The return value of getValues() is assigned to x and y, respectively.
    // Unlike structured binding, reuse existing variables
    std::tie(x, y) = getValues();
    
    std::cout << "x: " << x << std::endl;
    std::cout << "y: " << y << std::endl;
    
    // std::ignore: Used when you want to ignore a specific element.
    // Discard the second element (double) and only accept the first.
    std::tie(x, std::ignore) = getValues();
std::cout << "x (update): " << x << std::endl;
    
    return 0;
}

output of power:

x: 42
y: 3.14
x (updated): 42

Comparison operations

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
struct Person {
    std::string name;
    int age;
    double height;
    
    // Compare with tuples
    auto asTuple() const {
        return std::tie(name, age, height);
    }
    
    bool operator<(const Person& other) const {
        return asTuple() < other.asTuple();
    }
    
    bool operator==(const Person& other) const {
        return asTuple() == other.asTuple();
    }
};
int main() {
    Person p1{"Alice", 25, 165.5};
    Person p2{"Bob", 30, 175.0};
    Person p3{"Alice", 25, 165.5};
    
    if (p1 < p2) {
        std::cout << "p1 < p2" << std::endl;
    }
    
    if (p1 == p3) {
        std::cout << "p1 == p3" << std::endl;
    }
    
    return 0;
}

output of power:

p1 < p2
p1 == p3

4. Practical example

Example 1: Returning multiple values

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
#include <cmath>
std::tuple<double, double, double> solveQuadratic(double a, double b, double c) {
    double discriminant = b * b - 4 * a * c;
    
    if (discriminant < 0) {
        return {NAN, NAN, discriminant};
    }
    
    double sqrtD = std::sqrt(discriminant);
    double x1 = (-b + sqrtD) / (2 * a);
    double x2 = (-b - sqrtD) / (2 * a);
    
    return {x1, x2, discriminant};
}
int main() {
    auto [x1, x2, discriminant] = solveQuadratic(1, -5, 6);
    
    if (std::isnan(x1)) {
std::cout << "No real root (discriminant: " << discriminant << ")" << std::endl;
    } else {
        std::cout << "x1: " << x1 << std::endl;
        std::cout << "x2: " << x2 << std::endl;
std::cout << "Discriminant: " << discriminant << std::endl;
    }
    
    return 0;
}

output of power:

x1: 3
x2: 2
Discriminant: 1

Example 2: Sorting containers

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
int main() {
    std::vector<std::tuple<int, std::string, double>> students = {
        {1, "Alice", 85.5},
        {2, "Bob", 92.0},
        {3, "Charlie", 78.5},
        {4, "David", 92.0},
        {5, "Eve", 85.5}
    };
    
    // Sort descending by score
    std::sort(students.begin(), students.end(), 
         {
            return std::get<2>(a) > std::get<2>(b);
        });
    
std::cout << "=== Score order ===" << std::endl;
    for (const auto& [id, name, score] : students) {
std::cout << name << ": " << score << "point" << std::endl;
    }
    
    // Sort by score, name
    std::sort(students.begin(), students.end(), 
         {
            auto score_a = std::get<2>(a);
            auto score_b = std::get<2>(b);
            if (score_a != score_b) {
                return score_a > score_b;
            }
            return std::get<1>(a) < std::get<1>(b);
        });
    
std::cout << "\n=== Score, name order ===" << std::endl;
    for (const auto& [id, name, score] : students) {
std::cout << name << ": " << score << "point" << std::endl;
    }
    
    return 0;
}

output of power: 아래 코드는 code를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

=== Score order ===
Bob: 92 points
David: 92 points
Alice: 85.5 points
Eve: 85.5 points
Charlie: 78.5 points
=== Score, by name ===
Bob: 92 points
David: 92 points
Alice: 85.5 points
Eve: 85.5 points
Charlie: 78.5 points

Example 3: Map key

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <map>
#include <iostream>
#include <string>
int main() {
    // composite key
    std::map<std::tuple<int, std::string>, double> scores;
    
    scores[{1, "Math"}] = 85.5;
    scores[{1, "English"}] = 92.0;
    scores[{2, "Math"}] = 78.5;
    scores[{2, "English"}] = 88.0;
    
    // check
    auto key = std::make_tuple(1, "Math");
    if (auto it = scores.find(key); it != scores.end()) {
        auto [student_subject, score] = *it;
        auto [id, subject] = student_subject;
std::cout << "student " << id << ", " << subject << ": " << score << "point" << std::endl;
    }
    
    // circuit
std::cout << "\n=== Total score ===" << std::endl;
    for (const auto& [key, score] : scores) {
        auto [id, subject] = key;
std::cout << "student " << id << ", " << subject << ": " << score << "point" << std::endl;
    }
    
    return 0;
}

output of power: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

Student 1, Math: 85.5 points
=== Total Score ===
Student 1, English: 92 points
Student 1, Math: 85.5 points
Student 2, English: 88 points
Student 2, Math: 78.5 points

5. Tuple operation

comparison

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
int main() {
    std::tuple<int, double> t1{42, 3.14};
    std::tuple<int, double> t2{42, 3.14};
    std::tuple<int, double> t3{42, 2.71};
    
    // comparison
    std::cout << "t1 == t2: " << (t1 == t2) << std::endl;  // 1
    std::cout << "t1 == t3: " << (t1 == t3) << std::endl;  // 0
    std::cout << "t1 < t3: " << (t1 < t3) << std::endl;    // 0
    std::cout << "t3 < t1: " << (t3 < t1) << std::endl;    // 1
    
    return 0;
}

output of power: 다음은 간단한 code 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

t1 == t2: 1
t1 == t3: 0
t1 < t3: 0
t3 < t1: 1

connect(tuple_cat)

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
#include <string>
int main() {
    std::tuple<int, double> t1{42, 3.14};
    std::tuple<std::string, bool> t2{"hello", true};
    
    // connection
    auto t3 = std::tuple_cat(t1, t2);
    // std::tuple<int, double, std::string, bool>
    
    auto [x, y, z, w] = t3;
    std::cout << x << ", " << y << ", " << z << ", " << w << std::endl;
    
    return 0;
}

output of power:

42, 3.14, hello, 1

6. Frequently occurring problems

Problem 1: Index

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 에러 처리를 통해 안정성을 확보합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
int main() {
    std::tuple<int, double, std::string> t{42, 3.14, "hello"};
    
    // ❌ Runtime index
    // int i = 0;
    // auto x = std::get<i>(t);  // error: i is not constexpr
    
    // ✅ Compile-time index
    auto x = std::get<0>(t);
    std::cout << "x: " << x << std::endl;
    
    return 0;
}

Issue 2: References

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
int main() {
    int x = 42;
    double y = 3.14;
    
    // ❌ Copy
    auto t1 = std::make_tuple(x, y);
    std::get<0>(t1) = 100;
    std::cout << "x: " << x << std::endl;  // 42 (unchanged)
    
    // ✅ See also
    auto t2 = std::tie(x, y);
    std::get<0>(t2) = 100;
    std::cout << "x: " << x << std::endl;  // 100 (changed)
    
    // ✅ forward_as_tuple
    auto t3 = std::forward_as_tuple(x, y);
    std::get<0>(t3) = 200;
    std::cout << "x: " << x << std::endl;  // 200
    
    return 0;
}

output of power:

x: 42
x: 100
x: 200

Issue 3: Size

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <iostream>
struct Point {
    int x, y;
};
int main() {
    // tuples have overhead
    std::tuple<int, int> t;
std::cout << "tuple size: " << sizeof(t) << std::endl;  // 8
    
    // struct has no overhead
    Point p;
std::cout << "struct size: " << sizeof(p) << std::endl;  // 8
    
    // complex tuple
    std::tuple<int, double, std::string> t2;
std::cout << "Complex tuple size: " << sizeof(t2) << std::endl;  // 48
    
    return 0;
}

output of power:

tuple size: 8
struct size: 8
Complex tuple size: 48

7. pair vs tuple

comparison

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <utility>
#include <iostream>
int main() {
    // pair: 2
    std::pair<int, double> p{42, 3.14};
    std::cout << "pair: " << p.first << ", " << p.second << std::endl;
    
    // tuple: multiple
    std::tuple<int, double, std::string> t{42, 3.14, "hello"};
    std::cout << "tuple: " << std::get<0>(t) << ", " 
              << std::get<1>(t) << ", " 
              << std::get<2>(t) << std::endl;
    
    return 0;
}

output of power:

pair: 42, 3.14
tuple: 42, 3.14, hello

Selection Guide

Featurespairtuple
Number of Elements2Multiple
Access.first, .secondstd::get<N>
ReadabilityHighlow
Usekey-value, coordinatesreturn multiple values ​​
다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
// ✅ pair: When there are two
std::pair<int, std::string> getUserInfo() {
    return {123, "Alice"};
}
// ✅ tuple: 3 or more
std::tuple<int, std::string, int, double> getUserDetails() {
    return {123, "Alice", 25, 165.5};
}
// ✅ struct: Named field (recommended)
struct User {
    int id;
    std::string name;
    int age;
    double height;
};

8. Practical example: database results

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <tuple>
#include <vector>
#include <iostream>
#include <string>
using Row = std::tuple<int, std::string, int, double>;
std::vector<Row> queryDatabase() {
    return {
        {1, "Alice", 25, 85.5},
        {2, "Bob", 30, 92.0},
        {3, "Charlie", 28, 78.5}
    };
}
void printResults(const std::vector<Row>& results) {
    std::cout << "ID\tName\tAge\tScore" << std::endl;
    std::cout << "---\t----\t---\t-----" << std::endl;
    
    for (const auto& [id, name, age, score] : results) {
        std::cout << id << "\t" << name << "\t" << age << "\t" << score << std::endl;
    }
}
double calculateAverage(const std::vector<Row>& results) {
    double total = 0;
    for (const auto& [id, name, age, score] : results) {
        total += score;
    }
    return total / results.size();
}
int main() {
    auto results = queryDatabase();
    
    printResults(results);
    
std::cout << "\nAverage score: " << calculateAverage(results) << std::endl;
    
    return 0;
}

output of power: 아래 코드는 code를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

ID	Name	Age	Score
---	----	---	-----
1	Alice	25	85.5
2	Bob	30	92
3	Charlie	28	78.5
Average score: 85.3333

organize

Key takeaways

  1. tuple: Grouping multiple values ​​(C++11)
  2. Access: std::get<N>, structured binding
  3. tie: Unpack to existing variable
  4. Compare: Lexicographic comparison
  5. Practical: Returning multiple values, temporary grouping

pair vs tuple

Featurespairtuple
Number of Elements2Multiple
Access.first, .secondstd::get<N>
ReadabilityHighlow
SizeSmallLarge
Usekey-value, coordinatesreturn multiple values ​​

Practical tips

Principle of use:

  • Returns multiple values
  • Temporary grouping
  • Comparison operations
  • Map composite key Performance:
  • Stack Allocation
  • With overhead (padding)
  • struct recommended for small cases
  • Compile time size caution:
  • Index is constexpr
  • Reference is tie/forward_as_tuple
  • Readability (consider struct)
  • Size overhead

Next steps


Good article to read together (internal link)

Here’s another article related to this topic.

Practical tips

These are tips that can be applied right away in practice.

Debugging tips

  • If you run into a problem, check the compiler warnings first.
  • Reproduce the problem with a simple test case

Performance Tips

  • Don’t optimize without profiling
  • Set measurable indicators first

Code review tips

  • Check in advance for areas that are frequently pointed out in code reviews.
  • Follow your team’s coding conventions

Practical checklist

This is what you need to check when applying this concept in practice.

Before writing code

  • Is this technique the best way to solve the current problem?
  • Can team members understand and maintain this code?
  • Does it meet the performance requirements?

Writing code

  • Have you resolved all compiler warnings?
  • Have you considered edge cases?
  • Is error handling appropriate?

When reviewing code

  • Is the intent of the code clear?
  • Are there enough test cases?
  • Is it documented? Use this checklist to reduce mistakes and improve code quality.

Keywords covered in this article (related search terms)

This article will be helpful if you search for C++, tuple, pair, structured-binding, C++11, etc.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3