Skip to main content
Code Review

Return to Question

edited tags
Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Tweeted twitter.com/#!/StackCodeReview/status/551916794706161666
Source Link
Wyzard
  • 241
  • 1
  • 4

Variadic template for concisely defining a tuple whose components are all the same type

C++11 provides a std::tuple template, but it requires the types of all the fields to be listed individually, which is inconvenient if there are many fields and they're all the same type. If I want a tuple of, say, 10 integers, instead of writing std::tuple<int, int, int, int, int, int, int, int, int, int>, I'd like to be able to just write something like tuple_of<10, int>.

To that end, I've written a template that expands a number into that many copies of a type:

template <unsigned int n, typename T>
struct tuple_of {
private:
 // Adds another copy of T to the list
 template <unsigned int m, typename... Ts>
 struct tuple_builder {
 using type = typename tuple_builder<m-1, T, Ts...>::type;
 };
 // Makes a tuple out of all the copies of T that have been listed
 template <typename... Ts>
 struct tuple_builder<0, Ts...> {
 using type = std::tuple<Ts...>;
 };
public:
 tuple_of() = delete; // Prevent accidental instantiation
 using type = typename tuple_builder<n, T>::type;
};
// Convenience alias
template <unsigned int n, typename T>
using tuple_of_t = typename tuple_of<n, T>::type;

Now you can write either tuple_of<10, int>::type or tuple_of_t<10, int>.

This works, but it seems a little awkward. A few things in particular bother me:

  • I don't really like having to write either ::type or the _t suffix of the convenience alias; I'd rather just write tuple_of<10, int>. I've followed the pattern established by the templates in the standard <type_traits> header — e.g. std::result_of_t<T> is an alias for std::result_of<T>::type — but tuple_of isn't a type trait so I don't know if I should be following that convention.

  • I've made the template a struct because that seems to be the norm for templates used in metaprogramming, but it contains a private helper template that I don't really want to expose, and it's a little weird to have private stuff in a struct.

  • This is the first variadic template I've written, so I'm not sure that my tuple_builder is the most elegant way to build a list of n copies of a type.

  • While testing, I accidentally created an instance of the template type itself, rather than the tuple type it produces, by writing tuple_of<10, int> instead of tuple_of<10, int>::type. To avoid that mistake in the future, I deleted the constructor. I don't know whether that's something templates like this "should" do; the templates in <type_traits> don't have deleted constructors.

Can this template be improved?

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /