我正在编写一个新容器,并试图遵守 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>::T
是 MyType
)。
因此,您当前的方法一般不会起作用,但规范要求的整个问题是 C++11 问题,因此 C++11 特定解决方案是可以的! :-)
关于c++ - enable_if 可以用作非额外参数(例如,用于构造函数)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13792413/