Using Structures
Let us explore how structs can be used in everyday programs. We are going to create a simple program to calculate operations on a 3D vector type.
#include <cmath>
#include <iostream>
auto magnitude(auto const x, auto const y, auto const z) -> double {
return std::sqrt(x * x + y * y + z * z);
}
auto main() -> int {
auto const x = 2.;
auto const y = 3.;
auto const z = 5.;
std::cout << "The magnitude of the vector is "
<< magnitude(x, y, z)
<< "units.\n";
return 0;
}
Refactoring with Tuples
We can make this code more concise by packing the data into a tuple. This allows the
type signature of magnitude()
to be much simpler; taking a single parameter, and
ensures all our data is collected together. However, using a tuple leaves room for
ambiguity in which piece of data has which meaning as none of the elements have names.
#include <cmath>
#include <iostream>
#include <tuple>
using vec3 = std::tuple<double, double, double>;
auto magnitude(vec3 const vec) -> double {
auto const& [x, y, z] = v;
return std::sqrt(x * x + y * y + z * z);
}
auto main() -> int {
auto const v = vec3 { 2., 3., 5. };
std::cout << "The magnitude of the vector is "
<< magnitude(v)
<< "units.\n";
return 0;
}
- The line starting with the
using
keyword is used introduce a type alias. This allows us to define a shorter name for a type we are using frequently. This is particularly useful for tuples such that we can distinguish two tuples of the same underlying types but with different purposes. - We could also have used
std::make_tuple()
to create our tuple object inmain()
however, I used the brace-initialized from with the type alias to make it clearer what typev
is supposed to be.
Refactoring with structs
We can add more meaning by create a vec3
struct with named x, y and z data members.
Now our magnitude()
function is able to access the member variables by name.
#include <cmath>
#include <iostream>
struct vec3 {
double x;
double y;
double z;
};
auto magnitude(vec3 const vec) -> double {
return std::sqrt(vec.x * vec.x
+ vec.y * vec.y
+ vec.z * vec.z);
}
auto main() -> int {
auto const v = vec3 { 2., 3., 5. };
std::cout << "The magnitude of the vector is "
<< magnitude(v)
<< "units.\n";
return 0;
}