自定义数组类:列表初始化的构造方法

时间:2014-10-15 20:41:32

标签: c++

我正在使用C ++编写一个自定义数组类(作为一个自我引导的练习),我不知道如何创建一个允许我按照以下方式执行某些操作的构造函数: / p>

#include "array.h"
#include <iostream>
int main()
{
    array<int> test = {1, 2, 3, 4};
    std::cout << test(1) << std::endl;
    return 0;
}

编译器(VS Express 2013)给出的错误是#34;没有构造函数array :: array [with T = int]&#34;匹配参数列表。参数类型是(int,int,int,int)。&#34;

我不确定调用一组元素枚举的构造函数是什么。我知道我已经正确地重载了​​operator()(const int&)。我也知道这(因为我不清楚的原因)有效:

#include "array.h"
#include <iostream>
int main()
{
    array<char> test = "abcd";
    std::cout << test(1) << std:: endl; // prints 'a', as expected. 
    std::cout << test(4) << std::endl; // prints 'd', as expected.
    return 0;
}

这是通过array(const T[])构造函数实现的:array<int> test = {1, 2, 3, ..., n}案例的解决方案是否相似?

提前感谢任何指导。

编辑:包含以下代码,以防万一。

template<typename T>
class array
{
public:
    typedef T* iterator;
    typedef const T* const_iterator;
private:
    iterator head;
    unsigned long elems;
public:
    array()
        : head(nullptr)
        , elems(0) {}
    array(const unsigned long &size)
        : head(size > 0 ? new T[size] : nullptr)
        , elems(size) {}
    array(const T[]);
    array(const array&);
    ~array() { delete[] head; }

    iterator begin() const { return head; }
    iterator end() const { return head != nullptr ? &head[elems] : nullptr; }
    unsigned long size() const { return elems; }

    array& operator=(const array&);
    T& operator()(const unsigned long&);
};

template<typename T>
array<T>::array(const T rhs[])
{
    unsigned long size = sizeof(rhs) / sizeof(T);
    head = new T[size];
    iterator pointer = begin();
    for (const_iterator i = &rhs[0]; i != &rhs[0] + size; i++)
        *pointer++ = *i;
}

template<typename T>
array<T>::array(const array<T> &rhs)
{
    head = new T[rhs.size()];
    iterator pointer = begin();
    for (const_iterator i = rhs.begin(); i != rhs.end(); i++)
        *pointer++ = *i;
}

template<typename T>
array<T>& array<T>::operator=(const array<T> &rhs)
{
    if (this != &rhs)
    {
        delete[] head;
        head = new T[rhs.size()];
        iterator pointer = begin();
        for (const_iterator i = rhs.begin(); i != rhs.end(); i++)
            *pointer++ = *i;
    }
    return *this;
}

template<typename T>
T& array<T>::operator()(const unsigned long &index)
{
    if (index < 1 || index > size())
    {
        // Add some error-handling here.
    }
    return head[index - 1];
}

1 个答案:

答案 0 :(得分:4)

#include <initializer_list>

// ...

template <typename T>
class array
{   
    // ... 
    array(std::initializer_list<T> il);    

// ...    
template <typename T>
array<T>::array(std::initializer_list<T> il)
{
    unsigned long size = il.size();
    head = new T[size];
    iterator pointer = begin();
    for (const T& i : il)
        *pointer++ = i;
}

// ...
array<int> test = {1, 2, 3, 4};

DEMO


建议的改进:

  1. array(const T rhs[]);相当于array(const T* rhs);,即指针,这意味着sizeof(rhs) / sizeof(T)表达式不会为您提供项目数。如果你想要const char*的特殊构造函数,那么如果array<char>不是T char特化或至少从重载解析中禁用此构造函数>

  2. head = new T[size]; default-初始化所有元素(为类型T的每个实例调用默认构造函数)。然后你调用一个赋值操作:*pointer++ = *i;。这可以通过使用 placement-new 来改进,例如::new ((void*)ptr) T(*i);,其中ptr是指向未初始化的原始内存缓冲区的指针,如new char[sizeof(T)*size]或从get_temporary_buffer


  3. 如果您想知道以下为什么array<char> test = { "abcd" };使用您当前的实现,那么这里有一个解释:

    1. array<T>类有一个构造函数const T[]T=char实例化为array<char>::array(const char*)

    2. 列表初始化可用于调用对象的构造函数。

    3. 您的const T[]构造函数不明确,这意味着您可以使用 copy-initialization 语法,如下所示:

      array<char> test = { "test" };
      
    4. sizeof(rhs) / sizeof(T)表达T=char虽然无效,如上所述,sizeof(char*) / sizeof(char)评估为4 / 1 = 4,(最可能)"test"

    5. 用于初始化的{{1}}正好有4个字母,祝你好运。

相关问题