我正在撰写一个新容器,并尝试遵守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
的迭代器范围构造函数的前面声明好吗?
答案 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特定的解决方案是可以的! : - )