简体   繁体   中英

Creating a type with a variable number of members

Normally, when writing a Vector type, I do something like the following:

template <typename Type>
struct Vector2{
    Type x;
    Type y;
};

...and then repeat for Vector3 , Vector4 and so on.

This made me wonder, is there a better way to do this? For example, by expressing the number of members this type must have through sometime like a template. I'm not sure how the compiler would know how each member would be named, but just wanted to check in case I'm missing a wonderful trick.

If your types are the same std::array can be helpful. You can then write your accessor functions as free-functions and get static assertions when the size is out of bounds. If your types are different, you could use std::tuple instead of std::array .

#include <array>
#include <iostream>

namespace X {

template<typename T>
using Vector2 = std::array<T, 2>;

template<typename T>
using Vector3 = std::array<T, 3>;

// named accessors, you might want to make the accepted parameter more
// specific, e.g. std::array<T,I>
template<typename T>
decltype(auto) x(T&& t) { return std::get<0>(std::forward<T>(t)); }
template<typename T>
decltype(auto) y(T&& t) { return std::get<1>(std::forward<T>(t)); }
template<typename T>
decltype(auto) z(T&& t) { return std::get<2>(std::forward<T>(t)); }

}

int main()
{
  X::Vector2<int> v = {1, 2};
  // you can use [] syntax
  std::cout << v[0] << " " << v[1] << std::endl;
  // or named access
  X::x(v) = 2;
  X::z(v); // static assertion triggered
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM