19

Obviously, you can't have an instance of type void in a well-formed program, so something like the following declaration won't compile:

std::tuple<void, double, int> tup;

However, as long as we're dealing strictly with types as opposed to objects, there seems to be no issue. For example, my compiler (GCC) lets me say:

typedef std::tuple<void, double, int> tuple_type;

This is interesting to me, because it seems that with C++0x we can just use std::tuple to perform a lot of the meta-programming tricks that earlier would have required the boost::mpl library. For example, we can use std::tuple to create a vector of types.

For example, suppose we want to create a vector of types representing a function signature:

We can just say:

template <class R, class... Args>
struct get_function_signature;

template <class R, class... Args>
struct get_function_signature<R(*)(Args...)>
{
    typedef std::tuple<R, Args...> type;
};

This seems to work, even if the function signature has a void type, as long as we never actually instantiate an instance of get_function_signature<F>::type.

However, C++0x is still new to me, and of course all implementations are still somewhat experimental, so I'm a bit uneasy about this. Can we really use std::tuple as a vector of types for meta-programming?

Channel72
  • 24,139
  • 32
  • 108
  • 180
  • 1
    I expect the `boost::mpl::vector` to be deprecated. Anyway most of the `boost::mpl` functionality and template metaprogramming in general will change considerably when support for variadic templates will increase. – Matthieu M. Feb 03 '11 at 12:35

2 Answers2

12

It does actually make sense that you can do

typedef std::tuple<void, double, int > tuple_type;

as long as you only use it as a type-list to use tuple_element on. Thus I can do

tuple_element<0,tuple_type>::type * param;

which will declare param as void*

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • It seems that some standard library implementations can't handle this even after years of other standard library implementations supporting it without issue. For example, GCC and Clang reject it unless Clang is using MSVC's standard library, and MSVC accepts it. – LB-- Sep 18 '15 at 00:36
0

Probably, tuple with void element is safe unless we instantiate it.
So, though we can't write as the following,

struct C : std::tuple< void > {...

I can't imagine the case that this usage is useful now. So, it won't matter.

Well, this also applies to std::pair. We can write simple type list as the following:

struct Nil;
typedef std::pair< void, std::pair< int, Nil > > t;

though somehow such pair usage seems to be rare.

Incidentally, tuple type list might fail in some SFINAE-like purpose. For example, the following code isn't compiled on ideone(gcc-4.5.1) when I tested:

std::tuple< void > f();
template< class T > char g( T const& );

int main() {
  sizeof g( f() );
}

So, I'm not sure that current type lists can be replaced completely with tuple in near future.

Ise Wisteria
  • 11,259
  • 2
  • 43
  • 26