Home > OS >  std::vector::emplace_back with a POD C [duplicate]
std::vector::emplace_back with a POD C [duplicate]

Time:09-27

I have a fairly bog standard Vector4 struct (the math kind not the C kind) which is a POD and is templated:


template<typename T>
struct Vector4 {
    T x, y, z, w;

    Vector4 operator (const Vector4& other) const { return Vector4{ x   other.x, y   other.y, z   other.z, w   other.w }; }
    Vector4 operator-(const Vector4& other) const { return Vector4{ x - other.x, y - other.y, z - other.z, w - other.w }; }
    Vector4 operator*(const Vector4& other) const { return Vector4{ x * other.x, y * other.y, z * other.z, w * other.w }; }
    Vector4 operator/(const Vector4& other) const { return Vector4{ x / other.x, y / other.y, z / other.z, w / other.w }; }
    Vector4 operator (const T& a) const { return Vector4{ x   a, y   a, z   a, w   a }; }
    Vector4 operator-(const T& a) const { return Vector4{ x - a, y - a, z - a, w - a }; }
    Vector4 operator*(const T& a) const { return Vector4{ x * a, y * a, z * a, w * a }; }
    Vector4 operator/(const T& a) const { return Vector4{ x / a, y / a, z / a, z / a }; }

    Vector4& operator =(const Vector4& other) { x  = other.x; y  = other.y; z  = other.z; w  = other.w; return *this; }
    Vector4& operator-=(const Vector4& other) { x -= other.x; y -= other.y; z -= other.z; w -= other.w; return *this; }
    Vector4& operator*=(const Vector4& other) { x *= other.x; y *= other.y; z *= other.z; w *= other.w; return *this; }
    Vector4& operator/=(const Vector4& other) { x /= other.x; y /= other.y; z /= other.z; w /= other.w; return *this; }
    Vector4& operator =(const T& a) { x  = a; y  = a; z  = a; w  = a; return *this; }
    Vector4& operator-=(const T& a) { x -= a; y -= a; z -= a; w -= a; return *this; }
    Vector4& operator*=(const T& a) { x *= a; y *= a; z *= a; w *= a; return *this; }
    Vector4& operator/=(const T& a) { x /= a; y /= a; z /= a; w /= a; return *this; }

    T& operator[](size_t index) { return *(reinterpret_cast<T*>(this)   index); }
};

using Vector4f = Vector4<float>;
using Vector4i = Vector4<int>;
using Vector4i32 = Vector4<int32_t>;
using Vector4ui32 = Vector4<uint32_t>;
using Vector4i64 = Vector4<int64_t>;
using Vector4ui64 = Vector4<uint64_t>;

The problem I am having is that I cant make a std::vector of my Vector4 class. When I try the following:

std::vector<ogl::Vector4f> vec;
vec.emplace_back(1.0f, 2.0f, 3.0f, 4.0f);

I get this compile error

'Vector4::Vector4': no overloaded function takes 4 arguments

I have my own vector (C kind not math kind) class that I use and I tried using emplace_back with it but I got the same error. I also tried using and not using allocators (in my custom vector class) and have tried almost everything under the sun!

I can fix this issue by defining a constructor, but then it doesn't become a POD anymore. Normal construction using brace initialization works fine so I don't what's wrong.

If anyone can explain why this is happening/how to fix this (or if this is normal behaviour) it would be most appreciated.

CodePudding user response:

emplace_back uses parentheses to initialize the value, which means a constructor is required to use it until C 20. C 20 introduced parenthesized initialization of aggregates, so you code becomes valid as is.

Until then you can just do

vec.push_back({1.0f, 2.0f, 3.0f, 4.0f});
  • Related