选择c ++中的哪个构造函数

see*_*uch 13 c++ constructor resolution

我正在通过构建我自己的vector版本来实践C++,名为"Vector".我有两个构造函数,填充构造函数和范围构造函数.他们的声明如下:

template <typename Type> 
class Vector {
public:
    // fill constructor
    Vector(size_t num, const Type& cont);

    // range constructor
    template<typename InputIterator> Vector(InputIterator first, InputIterator last);

    /* 
    other members
    ......
    */
}
Run Code Online (Sandbox Code Playgroud)

填充构造函数用num的num填充容器; 并且范围构造函数将[first,last]范围内的每个值复制到容器中.它们应该与STL向量的两个构造函数相同.

他们的定义如下:

//fill constructor 
template <typename Type> 
Vector<Type>::Vector(size_t num, const Type& cont){
    content = new Type[num];
    for (int i = 0; i < num; i ++)
        content[i] = cont;
    contentSize = contentCapacity = num;
}

// range constructor
template <typename Type> 
template<typename InputIterator>
Vector<Type>::Vector(InputIterator first, InputIterator last){
    this->content = new Type[last - first];

    int i = 0;
    for (InputIterator iitr = first; iitr != last; iitr ++, i ++)
    *(content + i) = *iitr;

    this->contentSize = this->contentCapacity = i;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用它们时,我有区别它们的问题.例如:

Vector<int> v1(3, 5);
Run Code Online (Sandbox Code Playgroud)

使用这行代码,我打算创建一个包含三个元素的Vector,每个元素都是5.但是编译器用于范围构造函数,将"3"和"5"都视为"InputIterator"的实例,这没有任何意外,会导致错误.

当然,如果我将代码更改为:

Vector<int> v1(size_t(3), 5);
Run Code Online (Sandbox Code Playgroud)

一切都很好,填充构造函数被调用.但这显然不直观且用户友好.

那么,有没有一种方法可以直观地使用填充构造函数?

Cha*_*via 12

您可以使用std::enable_if(或者boost::enable_if如果您不使用C++ 11)来消除构造函数的歧义.

#include <iostream>
#include <type_traits>
#include <vector>
using namespace std;


template <typename Type> 
class Vector {
public:
    // fill constructor
    Vector(size_t num, const Type& cont)
    { 
        cout << "Fill constructor" << endl;
    }

    // range constructor
    template<typename InputIterator> Vector(InputIterator first, InputIterator last,
        typename std::enable_if<!std::is_integral<InputIterator>::value>::type* = 0)
    { 
        cout << "Range constructor" << endl;
    }

};

int main()
{
    Vector<int> v1(3, 5);
    std::vector<int> v2(3, 5);
    Vector<int> v3(v2.begin(), v2.end());
}
Run Code Online (Sandbox Code Playgroud)


上面的程序应首先通过检查类型是否为整数类型(因此不是迭代器)来调用fill构造函数.


顺便说一句,在你的范围构造函数的实现中,你应该使用std::distance(first, last)而不是last - first.-在迭代器上显式使用运算符会限制您使用RandomAccessIterator类型,但是您希望支持InputIterator哪种类型是Iterator的最通用类型.