C++ Dependent Name

In C++, a dependent name refers to a name (e.g., a type, variable, function, or template) whose meaning depends on a template parameter.

This concept arises in the context of templates, where the compiler cannot fully resolve certain names until the template is instantiated with specific types or values.

1. Introduction

When the compiler processes a template definition, it performs a two-phase lookup:

  1. Non-dependent names: Resolved at the point of template definition (when the template is written).
  2. Dependent names: Resolved at the point of template instantiation (when the template is used with concrete types).

Because dependent names rely on template parameters, the compiler delays their resolution until it knows the actual types involved. This introduces some special rules and syntax, like the typename and template keywords, to help the compiler distinguish between types and non-types or to access nested template members.

2. An all-in-one example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>

// A helper struct with various dependent elements
struct MyStruct {
using value_type = int; // Dependent type

static double scale; // Dependent variable

void process() { // Dependent function
std::cout << "Processing in MyStruct\n";
}

// Templated member function with a return value
template <typename U>
U transform(U value) {
std::cout << "Transforming: " << value << "\n";
return value * 2;
}
};

// Define the static variable
double MyStruct::scale = 2.5;

// A template class that uses dependent names
template <typename T>
class Worker {
public:
void run(T obj, float input) {
// 1. Dependent Type
typename T::value_type result = 10;

// 2. Dependent Variable
double scaled = input * T::scale;

// 3. Dependent Function Call
obj.process();

// 4. Dependent Function Template with Return Value
float transformed = obj.template transform<float>(scaled); // Capture return value

std::cout << "Result: " << result << ", Scaled: " << scaled
<< ", Transformed: " << transformed << "\n";
}
};

int main() {
MyStruct s;
Worker<MyStruct> w;
w.run(s, 4.0f);
return 0;
}
Author

Joe Chu

Posted on

2025-02-27

Updated on

2025-02-27

Licensed under

Comments