c++ - enable_if 可以用作非额外参数(例如,用于构造函数)吗?

标签 c++ stl template-meta-programming

我正在编写一个新容器,并试图遵守 N3485 23.2.3 [sequence.reqmts]/14,其中规定:

For every sequence container defined in this Clause and in Clause 21:

  • If the constructor

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

    is called with a type InputIterator that does not qualify as an input iterator, then the constructor shall not participate in overload resolution.

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

N3485 23.2.3 [sequence.reqmts]/15 说:

The extent to which an implementation determines that a type cannot be an input iterator is unspecified, except that as a minimum integral types shall not qualify as input iterators.

我的理解是,短语“不得参与重载决议”意味着容器实现者应该使用 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 的迭代器范围构造函数的前面声明是否可以?

最佳答案

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

但是,让我在这里指出做

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

挫败论证推论

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

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

关于c++ - enable_if 可以用作非额外参数(例如,用于构造函数)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13792413/

相关文章:

c++ - Qt-从资源中添加自定义字体

c++ - 想要使用 STL 在 C++ 中扫描二维数组

c++ - 如果我们不想将每个元素转换为一个转换元素,而是两个,我们如何使用 std::transform?

c++ - 将 constexpr 数组扩展为一组非类型模板参数

C++ 编译时条件运行时语句

c++ - Dev C++ 中用于 win32 程序的 drawtext 选项

c++ - C++ 流是如何工作的?

c++ - 使用 Lambda/Template/SFINAE 自动化 try/catch-safeguarding trampoline 函数

c++ - C++中静态变量的存储位置是什么时候确定的?

c++ - 如何有效删除存储在多个容器中的C++对象?自动指针?