User Defined Literals

User-Defined Literals and Template Classes

How do user-defined literals work with template classes?

Abstract art representing computer programming

User-defined literals can be used with template classes to create flexible and reusable code. Here’s how you can integrate user-defined literals with template classes:

Defining Template Classes

First, let's define a template class Quantity that can represent different types of measurements (e.g., distance, weight, etc.):

#include <iostream>

template <typename Unit>
class Quantity {
 public:
  explicit Quantity(float value)
    : value{value} {}
  float value;
};

template <typename Unit>
std::ostream& operator<<(
  std::ostream& os, const Quantity<Unit>& q) {
  os << q.value << " " << Unit::name();
  return os;
}

Defining User-Defined Literals

Next, we’ll define user-defined literals for specific units. Each unit will be a class with a static method name() to provide the unit’s name:

#include <iostream>

class Quantity {/*...*/}; struct Meters { static std::string name() { return "meters"; } }; struct Kilometers { static std::string name() { return "kilometers"; } }; Quantity<Meters> operator""_m(long double val) { return Quantity<Meters>{static_cast<float>(val)}; } Quantity<Kilometers> operator""_km(long double val) { return Quantity<Kilometers>{static_cast<float>(val)}; } int main() { auto distance1 = 5.0_m; auto distance2 = 3.5_km; std::cout << distance1 << "\n"; std::cout << distance2 << "\n"; }
5 meters
3.5 kilometers

Benefits of Using Template Classes

  • Type Safety: Template classes ensure that operations are type-safe. For example, you cannot mistakenly add distances and weights.
  • Reusability: You can define new units easily by creating new unit structs and corresponding user-defined literals.

Combining with Other Templates

You can combine user-defined literals with other templates, such as conversion functions. The following example has a convertTo() template function within the Quantity template class.

We then use template specialization to provide an implementation of that function for converting kilometers to meters:

#include <iostream>
#include <string>

template <typename Unit>
class Quantity {
 public:
  explicit Quantity(float value)
    : value{value} {}
  float value;

  float getValue() const { return value; }

  template <typename U>
  Quantity<U> convertTo() const;
};

template <typename Unit>
std::ostream& operator<<(
  std::ostream& os, const Quantity<Unit>& q) {
  os << q.value << " " << Unit::name();
  return os;
}

struct M {
  static std::string name() {
    return "meters";
  }
};

struct KM {
  static std::string name() {
    return "kilometers";
  }
};

template <>
template <>
Quantity<M> Quantity<KM>::convertTo<M>() const {
  return Quantity<M>{value * 1000};
}

Quantity<M> operator""_m(long double val) {
  return Quantity<M>{static_cast<float>(val)};
}

Quantity<KM> operator""_km(long double val) {
  return Quantity<KM>{static_cast<float>(val)};
}

int main() {
  auto distance1 = 5.0_m;
  auto distance2 = 1.5_km;

  auto distance_m = distance2.convertTo<M>();

  std::cout << distance1 << "\n";
  std::cout << distance2 << "\n";
  std::cout << distance_m << "\n";
}
5 meters
1.5 kilometers
1500 meters

Conclusion

Using user-defined literals with template classes enhances the expressiveness and reusability of your code.

Template classes provide a type-safe way to manage different units and operations, while user-defined literals offer a convenient syntax for creating these objects. This combination is powerful for writing clear, maintainable, and flexible C++ code.

Answers to questions are automatically generated and may not have been reviewed.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved