【问题标题】:Void type in std::tuplestd::tuple 中的空类型
【发布时间】:2011-06-20 13:57:40
【问题描述】:

显然,您不能在格式良好的程序中拥有 void 类型的实例,因此类似以下声明的内容无法编译:

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&lt;F&gt;::type 的实例。

不过,C++0x 对我来说还是个新手,当然所有的实现都还有些实验性,所以我对此有点不安。我们真的可以使用std::tuple 作为元编程的类型向量吗?

【问题讨论】:

  • 我希望 boost::mpl::vector 被弃用。无论如何,当对可变参数模板的支持增加时,大多数boost::mpl 功能和模板元编程一般都会发生很大变化。

标签: c++ c++11 tuples


【解决方案1】:

你可以这样做确实很有意义

typedef std::tuple&lt;void, double, int &gt; tuple_type;

只要你只使用它作为类型列表来使用tuple_element 就可以了。这样我就可以了

tuple_element&lt;0,tuple_type&gt;::type * param;

这会将参数声明为void*

【讨论】:

  • 似乎一些标准库实现即使在多年其他标准库实现支持它而没有问题之后也无法处理这个问题。例如,GCC 和 Clang 拒绝它,除非 Clang 使用 MSVC 的标准库,并且 MSVC 接受它。
【解决方案2】:

可能,tuplevoid 元素是安全的,除非我们实例化它。
所以,虽然我们不能写成下面这样,

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    相关资源
    最近更新 更多