C++ CTAD | Class Template Argument Deduction (C++17)
이 글의 핵심
Learn C++17 CTAD: omit template arguments for pair, vector, and custom types. Deduction guides, explicit constructors, and common pitfalls with initializer_list.
Introduction
CTAD (Class Template Argument Deduction), introduced in C++17, deduces class template arguments from constructor arguments so you can omit explicit template parameters.
1. CTAD basics
C++14 vs C++17
// C++14: explicit types
std::pair<int, double> p(1, 3.14);
std::vector<int> vec = {1, 2, 3};
// C++17: deduced
std::pair p(1, 3.14);
std::vector vec = {1, 2, 3};
Standard library
#include <vector>
#include <map>
#include <tuple>
#include <array>
int main() {
std::pair p(1, "Hello");
std::tuple t(1, 2.0, "Hi");
std::vector vec = {1, 2, 3};
std::map m = {{"a", 1}, {"b", 2}};
}
2. Custom class CTAD
Basic example
template<typename T>
class Container {
T value;
public:
Container(T v) : value(v) {}
T get() const { return value; }
};
int main() {
Container c(42);
Container c2(3.14);
Container c3("Hello");
}
Copy construction
template<typename T>
class Wrapper {
T value;
public:
Wrapper(T v) : value(v) {}
Wrapper(const Wrapper& other) : value(other.value) {}
T get() const { return value; }
};
3. Deduction guides
Simple guide
template<typename T>
class MyClass {
T value;
public:
MyClass(T v) : value(v) {}
};
template<typename T>
MyClass(T) -> MyClass<T>;
Custom conversions
template<typename T>
class Container {
T value;
public:
Container(T v) : value(v) {}
T get() const { return value; }
};
Container(const char*) -> Container<std::string>;
Iterator / nested types
Guides can map (It, It) to vector<value_type_t<It>>—the standard library does this for several constructors.
4. Common pitfalls
Ambiguous deduction
Multiple constructors can compete; guides disambiguate intent.
initializer_list and CTAD
Brace initialization can prefer initializer_list constructors—sometimes surprising; be explicit when needed.
const char* and std::string
Pairs of string literals may deduce to pair<string,string> if you construct that way explicitly; know your overload set.
5. Disabling deduction
explicit constructors do not participate in implicit copy-list-initialization patterns the same way—use explicit types when you must.
6. Examples: smart pointer–style, typed IDs
The article includes SmartPtr(T*) -> SmartPtr<T> and typed identifier wrappers—same code as the Korean version.
Summary
- CTAD deduces class template parameters from constructors (C++17).
- Deduction guides customize that mapping.
- Standard library types commonly use CTAD.
- Cost: compile-time only; no runtime overhead.
Trade-offs
| Pros | Cons |
|---|---|
| Shorter code | Types can be less visible at a glance |
| Still type-safe | Ambiguity if overloads clash |
| Compile-time | Requires C++17+ |
Tips
- Prefer CTAD when types are obvious.
- Spell out template arguments when readability wins.
- Use guides for conversions like
const char*→std::string.
Related posts
Keywords
C++, CTAD, class template argument deduction, deduction guide, C++17.
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Learn C++17 CTAD: omit template arguments for pair, vector, and custom types.
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.
Related Articles (Internal Links)
Other articles related to this topic.
- C++ Deduction Complete Guides | ‘추론 가이드’ 가이드
- C++ if constexpr | ‘컴파일 타임 if’ 가이드
- C++ 초기화 리스트 생성자 | ‘Initializer List’ 가이드
Keywords Covered in This Article (Related Search Terms)
This article covers C++, CTAD, Templates, C++17, Deduction.