enable_if可以用作非额外参数(例如构造函数)吗?

时间:2012-12-09 22:14:39

标签: c++ stl template-meta-programming

我正在撰写一个新容器,并尝试遵守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技巧来禁用该构​​造函数或成员函数。对于会员功能,这没什么大不了的;因为函数的返回类型是使用enable_if的常规方法。但是对于构造函数,没有可以应用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 docs建议使用初始化为nullptr的虚拟指针参数,而不是使用函数的实际参数。这对于正确的行为是必要的还是path的迭代器范围构造函数的前面声明好吗?

1 个答案:

答案 0 :(得分:3)

Good Robot(R。Martinho Fernandes)用干净的C ++ 11解决方案讨论了这个问题,即使用默认模板参数来应用enable_if his blog

但是,让我在这里指出做

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

箔片参数扣除

通过显式提供模板参数,仍然可以调用该函数。但是在C ++中,编译器只会拒绝匹配,例如形式参数类型MyType的{​​{1}}实际参数,因为虽然这可以在某些特殊情况下完成但不能总是这样做(Something<Blah>::T可能有无数的Blah选项} Something<Blah>::T)。

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