如何明确实现序列容器的填充构造函数和范围构造函数 [英] How to implement fill constructor and range constructor for sequence containers unambiguously

查看:258
本文介绍了如何明确实现序列容器的填充构造函数和范围构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

序列容器需要具有填充构造函数和范围构造函数,即,假设 MyContainer 建模其 value_type int size_type std :: size_t

Sequence containers need to have fill constructors and range constructors, i.e. these must both work, assuming MyContainer models a sequence container whose value_type is int and size_type is 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());

麻烦的是,我不确定如何实现这两个构造函数。这些签名无效。

Trouble is, I'm not sure how to implement these two constructors. These signatures don't work:

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);

在这种情况下,类似于上面示例1的实例选择范围构造函数而不是填充构造函数,因为 4 是一个整数,而不是 size_type 。如果我通过了 4u ,它会起作用,但是如果我正确理解了要求,则任何正整数都应该起作用。

In this case, an instantiation like in example 1 above selects the range constructor instead of fill constructor, since 4 is an int, not a size_type. It works if I pass in 4u, but if I understand the requirements correctly, any positive integer should work.

如果我在大小类型上模板化fill构造函数以允许其他整数,则当 value_type 与所使用的整数类型相同时,调用将不明确。

If I template the fill constructor on the size type to allow other integers, the call is ambiguous when value_type is the same as the integer type used.

我看了 std :: vector 的Visual C ++实现,他们使用一些特殊的魔术仅在模板时启用范围构造函数参数是一个迭代器( _Is_iterator< _Iter> )。我找不到用标准C ++实现此方法的任何方法。

I had a look at the Visual C++ implementation for std::vector and they use some special magic to only enable the range constructor when the template argument is an iterator (_Is_iterator<_Iter>). I can't find any way of implementing this with standard C++.

所以我的问题是...如何使它工作?

So my question is... how do I make it work?

注意:我没有使用C ++ 11编译器,并且没有选择boost。

Note: I am not using a C++11 compiler, and boost is not an option.

推荐答案

我认为您拥有正确的解决方案空间:要么通过仅显式传入 n s,或使用SFINAE将范围构造函数仅应用于实际的迭代器。不过,我要指出的是,MSVC的 _Is_iterator 没有任何魔力(也就是说,没有基于实现特定的扩展)。该源可用,并且基本上只是一个静态测试,该类型不是整数。有很多样板代码对其进行备份,但这都是标准C ++。

I think you've got the solution space right: Either disambiguate the call by passing in only explicitly size_t-typed ns, or use SFINAE to only apply the range constructor to actual iterators. I'll note, however, that there's nothing "magic" (that is, nothing based on implementation-specific extensions) about MSVC's _Is_iterator. The source is available, and it's basically just a static test that the type isn't an integral type. There's a whole lot of boilerplate code backing it up, but it's all standard C++.

当然,第三个选择是添加另一个fill构造函数重载,这需要一个签名大小。

A third option, of course, would be to add another fill constructor overload which takes a signed size.

这篇关于如何明确实现序列容器的填充构造函数和范围构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆