Search code examples
c++initializer-list

Error with initializer_list<initializer_list<T>>


I want to initialize my own class similar to this:

vector< Point3f >={{1f,2f,3f},{2f,3f,1f},{2f,2f,2f}};

but there is an error shown:

can't convert “initializer list” to “std::vector<LB::Point3f,std::allocator<LB::Point3f>>...

I want to know what the right way is to initialize my own class with lists in braces.

This is my code:

#pragma once
#ifndef POINT_HPP
#define POINT_HPP

#include<initializer_list>

namespace LB
{
    using namespace std;

    template< typename T,unsigned length>
    class Point
    {
        T data[length];
    public:
        Point(){}
        Point(const initializer_list<T>& t)
        {
            int min = t.size() < length ? t.size() : length;
            int i = 0;
            for (auto& each : t)
            {
                if (i >= min)
                    break;
                data[i] = each;
                i++;
            }
        }
        Point(Point<T, length>& other)
        {
            for (int i = 0; i < length; i++)
            {
                data[i] = other[i];
            }
        }
/*
   other operation function
*/
    };

    using Point2i = Point<int, 2>;
    using Point2f = Point<float, 2>;
    using Point2d = Point<double, 2>;
    using Point3i = Point<int, 3>;
    using Point3f = Point<float, 3>;
    using Point3d = Point<double, 3>;
    using Point4i = Point<int, 4>;
    using Point4f = Point<float, 4>;
    using Point4d = Point<double, 4>;
}

#endif

Solution

  • Basically it's failing because your current implementation of `Point<T,unsigned> doesn't have a working copy constructor.

    The copy constructor needs to take a const Point<T, length>& since the initializer list is const, and it will need a const version of operator[], given your current implementation of copy, because the argument of the copy constructor is a reference to your custom point class, not an array.

    Code below:

    #include <iostream>
    #include<initializer_list>
    #include <vector>
    
    namespace LB
    {
        template< typename T, unsigned length>
        class Point
        {
            T data[length];
        public:
            Point() {}
            Point(const std::initializer_list<T>& t)
            {
                int min = t.size() < length ? t.size() : length;
                int i = 0;
                for (auto& each : t)
                {
                    if (i >= min)
                        break;
                    data[i] = each;
                    i++;
                }
            }
    
            Point(const Point<T, length>& other)
            {
                for (size_t i = 0; i < length; i++)
                {
                    data[i] = other[i];
                }
            }
    
            T& operator[](size_t i) {
                return data[i];
            }
       
            const T& operator[](size_t i) const {
                return const_cast<const T&>(
                    const_cast<Point&>(*this)[i]
                );
            }
        };
    
        using Point3f = Point<float, 3>;
    }
    
    int main() {
        std::vector<LB::Point3f> vec = { {1.0f,2.0f,3.0f},{2.0f,3.0f,1.0f},{2.0f,2.0f,2.0f} };
        std::cout << vec[1][0] << " , " << vec[1][1] << " , " << vec[1][2] << "\n";
    }