2011-02-03 139 views
16

很显然,你不能有void类型的实例在一个结构良好的程序,所以像下面的声明不会编译:void类型的std ::元组

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

然而,随着只要我们严格对待类型而不是对象,似乎就没有问题了。例如,我的编译器(GCC)让我说:

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

这是对我有意思,因为它似乎与的C++ 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的实例。然而,C++ 0x对我来说仍然是新的,当然所有的实现都还是有点实验性的,所以我对此有点不安。我们真的可以使用std::tuple作为元编程类型的向量吗?

+1

我期望`boost :: mpl :: vector`不推荐使用。无论如何,当对可变参数模板的支持增加时,大多数boost :: mpl功能和模板元编程通常都会发生很大的变化。 – 2011-02-03 12:35:16

回答

10

它实际意义,你可以做

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

只要你只把它当作一个类型列表上使用tuple_element。因此,我可以做

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

void*

+0

似乎有些标准库实现甚至在多年其他标准库实现支持它没有问题之后仍无法处理。例如,GCC和Clang拒绝它,除非Clang使用MSVC的标准库,并且MSVC接受它。 – 2015-09-18 00:36:51

0

也许,tuplevoid要素是安全的,除非我们将它实例化,这将宣告PARAM。
所以,虽然我们不能写为下面

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在不久的将来取代。

相关问题