I have a class called Shape, which can be initialized from any iterable, and a class called Array, which simply contains a Shape. However, I'm getting a compile error I can't explain when I try to initialize an Array:
class Shape
{
public:
template<typename Iterator>
Shape(Iterator first, Iterator last)
: m_shape(first, last) {}
template <typename Iterable>
Shape(const Iterable& shape)
: Shape(shape.begin(), shape.end()) {}
template<typename T>
Shape(std::initializer_list<T> shape)
: Shape(shape.begin(), shape.end()) {}
private:
std::vector<std::size_t> m_shape;
};
class Array
{
public:
Array(const Shape& shape)
: m_shape(shape) {}
private:
Shape m_shape;
};
int main() {
Shape s{0}; // ok
Array a1({1, 2}); // ok
Array a2({0}); // error
}
The compilation error appears on the second constructor of Shape:
prog.cxx:35:16: required from here
prog.cxx:14:23: error: request for member ‘begin’ in ‘shape’, which is of non-class type ‘const int’
: Shape(shape.begin(), shape.end()) {}
~~~~~~^~~~~
prog.cxx:14:38: error: request for member ‘end’ in ‘shape’, which is of non-class type ‘const int’
: Shape(shape.begin(), shape.end()) {}
~~~~~~^~~
I don't understand what is happening here. Why is the Iterable constructor called instead of the initializer_list<T> constructor? What's the difference between the Shape constructor with {0} and the Array constructor?
s5line) with my g++ 6.3.0 and with my clang++ 3.8.1 (I mean... if you correctNDShape, for the second constructor, inShape, obviously). Which compiler are you using?