Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A deduction guide is a declarative mechanism introduced in C++17 that dictates how the compiler should deduce class template arguments from the types of the arguments passed to a constructor. It forms the foundation of Class Template Argument Deduction (CTAD), allowing the instantiation of template classes without explicitly specifying the template parameters.

Syntax

A user-defined deduction guide must be declared in the same scope (namespace or enclosing class) as the primary class template.
template <parameter-list>
[explicit] class-name(parameter-declaration-list) -> class-name<template-argument-list>;
  • template <parameter-list>: The template parameters used in the guide. These often mirror the class or constructor template parameters.
  • [explicit]: An optional specifier that restricts the deduction guide from being considered during copy-initialization contexts.
  • class-name(parameter-declaration-list): A signature resembling a constructor declaration. It represents the arguments being passed during instantiation.
  • -> class-name<template-argument-list>: The trailing return type indicating the exact template instantiation the compiler should generate when the argument list matches.

The All-or-Nothing Rule

Class Template Argument Deduction is strictly an all-or-nothing mechanism. If a developer explicitly provides any template arguments during instantiation, CTAD and all associated deduction guides are completely disabled. The compiler will not attempt to partially deduce the remaining template parameters.
template <typename T, typename U>
struct Pair {
    Pair(T, U);
};

Pair p1(1, 2.0);              // Valid: CTAD deduces Pair<int, double>
Pair<int, double> p2(1, 2.0); // Valid: Exact template arguments provided, CTAD bypassed
Pair<int> p3(1, 2.0);         // Error: Partial specification disables CTAD; missing argument for U

Implicit vs. User-Defined Guides

Implicit Deduction Guides When a class template is defined, the compiler automatically generates implicit deduction guides for every constructor in the primary template. The return type of an implicitly generated deduction guide is always the primary class template parameterized by its template parameters.
template <typename T>
struct Wrapper {
    Wrapper(T* value); 
    // Compiler implicitly generates: 
    // template<typename T> Wrapper(T*) -> Wrapper<T>;
};

int value = 42;
Wrapper w(&value); // Deduces Wrapper<int> via the implicit guide
User-Defined Deduction Guides User-defined guides are required when implicit deduction yields an incorrect type, when constructors accept types that differ from the class template parameters (e.g., iterators), or when type traits must be applied to the deduced types.
#include <iterator>

template <typename T>
struct Sequence {
    template <typename Iterator>
    Sequence(Iterator first, Iterator last);
};

// User-defined deduction guide mapping iterator types to their underlying value type
template <typename Iterator>
Sequence(Iterator, Iterator) -> Sequence<typename std::iterator_traits<Iterator>::value_type>;

Overload Resolution Mechanics

When a developer invokes CTAD by omitting template arguments (e.g., Type name(args...);), the compiler constructs a set of candidate functions to perform overload resolution. This candidate set consists of:
  1. All user-defined deduction guides associated with the class template.
  2. All implicitly generated deduction guides derived from the class constructors.
  3. A synthesized copy deduction guide (to handle Type t2 = t1;).
The compiler applies standard C++ function overload resolution rules to this candidate set based on the provided arguments. If a user-defined guide and an implicit guide are equally viable matches, the C++ standard dictates that the user-defined guide is preferred.

The explicit Specifier

Applying the explicit keyword to a deduction guide enforces strict initialization rules. If a deduction guide is marked explicit, it will only be considered during direct-initialization contexts and will be discarded from the candidate set during copy-initialization contexts. When the explicit guide is discarded, the compiler evaluates the remaining candidates (such as the implicit guides), which can result in a different deduced type depending on the initialization syntax.
#include <string>

template <typename T>
struct Container {
    Container(T value); 
    // Implicit guide: template <typename T> Container(T) -> Container<T>;
};

// Explicit user-defined deduction guide
explicit Container(const char*) -> Container<std::string>;

// Direct-initialization: 
// The explicit user-defined guide is viable and preferred over the implicit guide.
// Deduces Container<std::string>.
Container c1{"text"}; 

// Copy-initialization: 
// The explicit guide is ignored. The compiler falls back to the implicit guide.
// Deduces Container<const char*>.
Container c2 = "text"; 
Master C++ with Deep Grasping Methodology!Learn More