Type Aliases with Const and Volatile
How do type aliases interact with const and volatile qualifiers?
Type aliases interact with const
and volatile
qualifiers in interesting ways. Understanding these interactions is crucial for writing correct and maintainable C++ code. Let's explore this topic with some examples.
Basic Interaction
When you create a type alias, you can add const
and volatile
qualifiers to it, or to the underlying type:
#include <iostream>
using Integer = int;
using ConstInteger = const int;
int main() {
Integer i{42};
ConstInteger ci{10};
// OK
i = 100;
// Error: assignment of read-only variable ci
ci = 20;
// This is equivalent to 'const int ci2{30};
const Integer ci2{30};
// Error: assignment of read-only variable ci2
ci2 = 40;
}
error: 'ci': you cannot assign to a variable that is const
error: 'ci2': you cannot assign to a variable that is const
Pointers and References
Things get more interesting with pointers and references:
using IntPtr = int*;
using ConstIntPtr = const int*;
using IntConstPtr = int* const;
int main() {
int value{42};
IntPtr p1{&value};
ConstIntPtr p2{&value};
IntConstPtr p3{&value};
*p1 = 10; // OK
// Error: assignment of read-only location
*p2 = 20;
*p3 = 30; // OK
int anotherValue{100};
p1 = &anotherValue; // OK
p2 = &anotherValue; // OK
// Error: assignment of read-only variable 'p3'
p3 = &anotherValue;
}
error: 'p2': you cannot assign to a variable that is const
error: 'p3': you cannot assign to a variable that is const
In this example:
IntPtr
is a pointer toint
ConstIntPtr
is a pointer toconst int
(can't modify the pointed-to value)IntConstPtr
is aconst
pointer toint
(can't change what it points to)
Adding Qualifiers to Aliases
You can add qualifiers to type aliases:
using Integer = int;
int main() {
// Equivalent to const int ci{42};
const Integer ci{42};
// Equivalent to volatile int vi{10};
volatile Integer vi{10};
// Error: assignment of read-only variable 'ci'
ci = 100;
// OK, but compiler won't optimize access to 'vi'
vi = 20;
}
error: 'ci': you cannot assign to a variable that is const
Templates and Type Aliases
Type aliases can be particularly useful with templates:
#include <iostream>
#include <vector>
template <typename T>
using ConstRef = const T&;
int main() {
std::vector<int> vec{1, 2, 3};
ConstRef<std::vector<int>> constVecRef = vec;
// Error: 'constVecRef' is read-only
constVecRef.push_back(4);
for (ConstRef<int> element : constVecRef) {
std::cout << element << ' ';
}
}
error: 'push_back()': cannot convert from 'const std::vector<int>' to 'std::vector<int>'
note: Conversion loses qualifiers
In this example, ConstRef<T>
is an alias template for a const reference to T
.
Understanding these interactions allows you to write more expressive and type-safe code. Remember, type aliases don't create new types - they're just new names for existing types. This means that the const
and volatile
qualifiers behave exactly as they would with the original types.
Type Aliases
Learn how to use type aliases and utilities to simplify working with complex types.