본문으로 건너뛰기 C++ Template Lambdas — Complete Guide

C++ Template Lambdas — Complete Guide

C++ Template Lambdas — Complete Guide

이 글의 핵심

C++20 template lambdas: []<typename T>(T a, T b), concepts constraints, parameter packs, and when they beat generic auto lambdas.

Introduction

C++20 template lambdas let you specify explicit template parameters on a lambda, giving you precise control and clean concept-based constraints.

1. Basics: auto vs template lambda

#include <iostream>
#include <typeinfo>
int main() {
    // C++14: generic lambda
    auto addAuto = [](auto a, auto b) {
        return a + b;
    };
    
    // C++20: template lambda — both parameters share T
    auto addTemplate = []<typename T>(T a, T b) {
        return a + b;
    };
    
    std::cout << addTemplate(1, 2) << std::endl;
    std::cout << addTemplate(1.5, 2.5) << std::endl;
    // addTemplate(1, 2.5);  // error: mismatched T
}

Printing with type info

auto print = []<typename T>(const T& value) {
    std::cout << "type: " << typeid(T).name()
              << ", value: " << value << std::endl;
};

Ideas

  • Explicit template parameters: <typename T>
  • Enforce relationships between parameters
  • Combine with concepts

2. Concepts

The following example demonstrates the concept in cpp:

#include <concepts>
auto addInts = []<std::integral T>(T a, T b) {
    return a + b;
};
auto addFloats = []<std::floating_point T>(T a, T b) {
    return a + b;
};

Custom concepts

template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
auto multiply = []<Numeric T>(T a, T b) {
    return a * b;
};

3. Practical examples

Example 1: Multiple template parameters

#include <iostream>
int main() {
    auto convert = []<typename From, typename To>(From value) {
        return static_cast<To>(value);
    };
    
    auto result1 = convert.operator()<int, double>(10);
    std::cout << result1 << std::endl;
    
    auto result2 = convert.operator()<double, int>(3.14);
    std::cout << result2 << std::endl;
    
    auto toInt = []<typename From>(From value) {
        return static_cast<int>(value);
    };
    
    std::cout << toInt(3.14) << std::endl;
}

Example 2: Containers

#include <iostream>
#include <vector>
#include <list>
#include <typeinfo>
int main() {
    auto printContainer = []<typename Container>(const Container& c) {
        using ValueType = typename Container::value_type;
        
        std::cout << "container: " << typeid(Container).name() << std::endl;
        std::cout << "value_type: " << typeid(ValueType).name() << std::endl;
        std::cout << "elements: ";
        
        for (const auto& item : c) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    };
    
    std::vector<int> vec = {1, 2, 3, 4, 5};
    printContainer(vec);
    
    std::list<double> lst = {1.1, 2.2, 3.3};
    printContainer(lst);
}

Example 3: Parameter packs

#include <iostream>
int main() {
    auto sum = []<typename... Ts>(Ts... values) {
        return (values + ...);
    };
    
    std::cout << sum(1, 2, 3) << std::endl;
    std::cout << sum(1.5, 2.5, 3.5) << std::endl;
    
    auto print = []<typename... Ts>(Ts... values) {
        ((std::cout << values << " "), ...);
        std::cout << std::endl;
    };
    
    print(1, 2, 3);
    print("Hello", 42, 3.14);
}

Example 4: Container transform

#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    auto transform = []<typename Container, typename Func>(
        const Container& input, 
        Func func
    ) {
        using ValueType = typename Container::value_type;
        Container output;
        
        for (const auto& item : input) {
            output.push_back(func(item));
        }
        
        return output;
    };
    
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    auto doubled = transform(numbers, [](int x) { return x * 2; });
    
    for (int n : doubled) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
}

Summary

  1. Template lambdas are C++20.
  2. Concepts constrain T (std::integral, custom concepts).
  3. Packs work: []<typename... Ts>(Ts... values).
  4. Explicit calls: .operator()<int>(...).

auto vs template lambda

Scenarioauto lambdaTemplate lambda
Independent parameter types❌ (unless multiple Ts)
Same T for multiple parameters
Concepts on T
Explicit template args

Keywords

C++, template lambda, C++20, concepts, generic lambda.

See also


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. C++20 template lambdas: []<typename T>(T a, T b), concepts constraints, parameter packs, and when they beat generic `a…

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, Lambda, Template, C++20, Generic.