enable_if是否可以用作非额外参数(例如,用于构造函数)

Can enable_if be used as a non-extra parameter (e.g. for a constructor)?

本文关键字:参数 例如 构造函数 用于 是否 if enable      更新时间:2023-10-16

我正在编写一个新的容器,并试图遵守N3485 23.2.3 [sequence.reqmts]/14,它声明:

对于本条款和第21条中定义的每个序列容器:

  • 如果构造函数

    template <class InputIterator>
    X(InputIterator first, InputIterator last, 
    const allocator_type& alloc = allocator_type())
    

    使用类型InputIterator调用,该类型不符合输入迭代器,则构造函数不应参与重载决议

(对于采用迭代器范围的成员函数,/14几乎逐字逐句地重复这一点)

N3485 23.2.3 [sequence.reqmts]/15说:

实现确定一个类型不能是输入迭代器的程度是未指定的,除非作为最低限度的积分类型不符合输入迭代者的条件。

我的理解是,短语"不应参与重载解决"意味着容器实现者应该在模板参数推导过程中使用SFINAE技巧禁用该构造函数或成员函数。对于成员功能而言,这没什么大不了的;因为函数的返回类型是使用CCD_ 5的正常方式。但是对于构造函数,没有可以应用enable_if的返回类型。这是我第一次尝试声明构造函数:

// The enable_if use below is to comply with 23.2.3 [sequence.reqmts]/14:
//     ... is called with a type InputIterator that does not qualify as an input iterator
//     then the constructor shall not participate in overload resolution.
template <typename InputIterator>
path(std::enable_if<!std::is_integral<InputIterator>::value, InputIterator>::type first,
InputIterator last, Allocator const& allocator = allocator_type());

然而,boost的enable_if文档建议使用初始化为nullptr的伪指针参数,而不是使用函数的实际参数。这是正确行为所必需的吗?还是path的迭代器范围构造函数的前面声明可以?

The Good Robot(R.Martinho Fernandes)在他的博客中讨论了一个干净的C++11解决方案的问题,即使用默认模板参数应用enable_if

然而,让我在这里指出,做

template< class Type >
void foo( typename Something< Type >::T )

反对论点推导

仍然可以通过显式提供模板参数来调用函数。但在C++中,编译器将简单地拒绝将例如MyType实际参数与形式参数类型Something<Blah>::T进行匹配,因为尽管在某些特殊情况下可以这样做,但它不能总是这样做(Blah可能有无数种选择,其中Something<Blah>::TMyType)。

因此,您当前的方法一般不起作用,但规范要求的整个问题是C++11问题,因此C++11特定的解决方案是可以的!:-)

相关文章: