Тип Void в std:: tuple
Очевидно, вы не можете иметь экземпляр типа void
в хорошо сформированной программе, поэтому что-то вроде следующего объявления не будет компилироваться:
std::tuple<void, double, int> tup;
Однако, если мы имеем дело исключительно с типами, а не с объектами, то, похоже, не проблема. Например, мой компилятор (GCC) позволяет мне сказать:
typedef std::tuple<void, double, int> tuple_type;
Мне это интересно, потому что кажется, что с С++ 0x мы можем просто использовать std::tuple
для выполнения многих метапрограммных трюков, которые раньше требовали бы библиотеки boost::mpl
. Например, мы можем использовать std::tuple
для создания вектора типов.
Например, предположим, что мы хотим создать вектор типов, представляющих сигнатуру функции:
Можно просто сказать:
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;
};
Кажется, что это работает, даже если подпись функции имеет тип void
, если мы фактически не создаем экземпляр get_function_signature<F>::type
.
Однако С++ 0x для меня все еще новичок, и, конечно, все реализации все еще несколько экспериментальны, поэтому я немного неспособен по этому поводу. Можем ли мы использовать std::tuple
как вектор типов для метапрограммирования?
Ответы
Ответ 1
Это действительно имеет смысл, что вы можете сделать
typedef std::tuple<void, double, int > tuple_type;
пока вы используете его только как список типов для использования tuple_element
on. Таким образом, я могу сделать
tuple_element<0,tuple_type>::type * param;
который объявит параметр как void*
Ответ 2
Возможно, tuple
с элементом void
безопасен, если мы не создадим его экземпляр.
Таким образом, хотя мы не можем писать следующее:
struct C : std::tuple< void > {...
Я не могу представить, что это использование полезно сейчас.
Таким образом, это не имеет значения.
Ну, это также относится к std::pair
.
Мы можем написать простой список типов следующим образом:
struct Nil;
typedef std::pair< void, std::pair< int, Nil > > t;
хотя каким-то образом такое использование pair
кажется редким.
Кстати, список типов tuple
может оказаться неудачным в некоторых целях, подобных SFINAE.
Например, следующий код не компилируется на ideone (gcc-4.5.1), когда я
тестирование:
std::tuple< void > f();
template< class T > char g( T const& );
int main() {
sizeof g( f() );
}
Итак, я не уверен, что списки текущего типа можно полностью заменить
tuple
в ближайшем будущем.