正确签名/检测Container :: reserve()的存在 [英] Correct signature of / detect presence of Container::reserve()

查看:133
本文介绍了正确签名/检测Container :: reserve()的存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个类型 C 这是一个符合STL的容器,如何正确检测 C 是否包含成员函数 reserve ?我试过下面的方法(用GCC 4.6.3):

Given a type C which is an STL-conforming container, how do I correctly detect if C contains a member function reserve? I tried the following approach (with GCC 4.6.3):

template< typename C, typename = void >
struct has_reserve
  : std::false_type
{};

template< typename C >
struct has_reserve< C, typename std::enable_if<
                         std::is_same<
                           decltype( &C::reserve ),
                           void (C::*)( typename C::size_type )
                         >::value
                       >::type >
  : std::true_type
{};

这适用于 C std :: vector ,但不能用于无序容器,例如 std :: unordered_set 。原因是 reserve std :: vector 的(直接)成员函数,但对于无序容器它继承自一个基类,即它的签名不是 void(C :: *)(typename C :: size_type),但 void对于 C 的某些未指定的基类 B $ c>。

This works for C being std::vector, but not for the unordered containers, e.g. std::unordered_set. The reason is, that reserve is a (direct) member function of std::vector, but for the unordered containers it is inherited from a base class, i.e., its signature is not void (C::*)( typename C::size_type ) but void (B::*)( typename C::size_type ) for some unspecified base class B of C.

我知道如何解决它并检测 reserve ,即使继承,但它看起来笨拙我不知道标准允许什么。所以...

I know how to work around it and detect reserve even if inherited, but it looks clumsy and I wonder what is allowed by the standard. So...

我的问题是:标准允许 reserve 从一个未指定的基类继承,是概要绑定,需要一个直接成员函数?

My question is: Does the standard allow reserve to be inherited from an unspecified base class or is the synopsis binding and requires a direct member function?

推荐答案

所有的标准都说关于从基类继承是允许:

All the standard says about inheritance from base classes is that it is allowed:


17.6.5.11派生类[衍生]



可以从保留给实现的名称的类中派生C ++标准库中的任何类。

17.6.5.11 Derived classes [derivation]

1 - An implementation may derive any class in the C++ standard library from a class with a name reserved to the implementation.

是否允许方法(以及实际上其他成员,如typedef)从基类继承;显然,由于实现这样做,标准应该描述这种行为。

It doesn't say either way whether methods (and, indeed, other members such as typedefs) are allowed to be inherited from a base class; obviously, since implementations do so, the standard should describe this behaviour.

在任何情况下, reserve 通过强制转换为成员函数类型,即使是最派生类型的成员也不能保证工作,因为:

In any case, detecting e.g. reserve by cast to a member function type is not guaranteed to work even if a member of the most derived type, since:


17.6.5.5成员函数[member.functions]



2 - 一个实现可以声明一个class:

17.6.5.5 Member functions [member.functions]

2 - An implementation may declare additional non-virtual member function signatures within a class:


  • 通过向成员函数签名 186添加具有默认值的参数; [...]

186)因此,C ++标准库中的类的成员函数的地址具有未指定的类型。

186) Hence, the address of a member function of a class in the C++ standard library has an unspecified type.

检查 reserve 是否存在的正确方法是尝试调用it:

The correct way to check whether reserve exists is to attempt to call it:

template< typename C, typename = void >
struct has_reserve
  : std::false_type
{};

template< typename C >
struct has_reserve< C, typename std::enable_if<
                         std::is_same<
                           decltype( std::declval<C>().reserve( std::declval<typename C::size_type>() ) ),
                           void
                         >::value
                       >::type >
  : std::true_type
{};

这具有并行容器需求的优点code> unordered_set ),这是规范的,其中的概要更倾向于信息。

This has the advantage of paralleling the container requirements (table 103 for unordered_set), which are normative where the synopses tend more to the informative.

这篇关于正确签名/检测Container :: reserve()的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆