序列容器需要有填充构造函数和范围构造函数,即这些必须兼有,假设MyContainer
模拟了value_type
为int
且size_type
为{的{1}}序列容器{1}}:
std::size_t
麻烦的是,我不确定如何实现这两个构造函数。这些签名不起作用:
// (1) Constructs a MyContainer containing the number '42' 4 times.
MyContainer<int> c = MyContainer<int>(4, 42);
// (2) Constructs a MyContainer containing the elements in the range (array.begin(), array.end())
std::array<int, 4> array = {1, 2, 3, 4};
MyContainer<int> c2 = MyContainer<int>(array.begin(), array.end());
在这种情况下,上面示例1中的实例化选择范围构造函数而不是填充构造函数,因为template<typename T>
MyContainer<T>::MyContainer(const MyContainer::size_type n, const MyContainer::value_type& val);
template<typename T>
template<typename OtherIterator>
MyContainer<T>::MyContainer(OtherIterator i, OtherIterator j);
是int,而不是4
。如果我传入size_type
,它会起作用,但如果我正确理解了这些要求,那么任何正整数都应该有效。
如果我在大小类型上模板填充构造函数以允许其他整数,那么当4u
与使用的整数类型相同时,调用是不明确的。
我查看了value_type
的Visual C ++实现,并且当模板参数是迭代器(std::vector
)时,它们使用一些特殊的魔法来仅启用范围构造函数。我找不到任何用标准C ++实现它的方法。
所以我的问题是......我该如何让它发挥作用?
注意:我没有使用C ++ 11编译器,并且不能使用boost。
答案 0 :(得分:1)
我认为你已经有了正确的解决方案空间:通过仅明确地传入size_t
- 类型n
来消除调用的歧义,或者使用SFINAE仅将范围构造函数应用于实际的迭代器。但是,我会注意到,对于MSVC的_Is_iterator
,没有什么“神奇的”(也就是说,没有基于特定于实现的扩展)。源是可用的,它基本上只是一个静态测试,类型不是整数类型。有很多样板代码备份它,但它都是标准的C ++。
第三个选项当然是添加另一个带有符号大小的填充构造函数重载。