class 联合使用构造函数上的已删除函数
class with union use of deleted function on constructor
我正在尝试制作一个 4*4 矩阵的 class,它是由 16 个浮点数组成的数组构建的,但我也想将它表示为 4 个 vec4 的数组(对于每个柱子)。
问题是它没有编译,并且在我调用 mat4 的构造函数的任何地方都会出错。
我的 mat4.h:
struct mat4 {
union
{
float elements[4 * 4]; // column major ordering, index = row + col * 4
vec4 columns[4];
};
mat4();
mat4(float diagonal);
mat4& mul(const mat4& other); //TODO: maybe return mat4
// vec4 getColumn(int colIndex);
static mat4 identity(); // construct and return an identity matrix
static mat4 orthographic(float left, float right, float bottom, float top, float near, float far); // boundaries (clipping planes)
static mat4 perspective(float fov, float aspectRatio, float near, float far);
static mat4 translation(const vec3& translation);
static mat4 scale(const vec3 &scale);
static mat4 rotation(float angle, const vec3 & axis);
friend mat4 operator*(mat4 left, const mat4 & right);
mat4& operator*=(const mat4 &other); //TODO: check that it fits with the vectors
friend std::ostream &operator<<(std::ostream &stream, const mat4 &m);
};
我的mat4.cpp:
#include "mat4.h"
mat4::mat4() {
for (int i = 0; i < 4 * 4; i++)
elements[i] = 0;
}
mat4::mat4(float diagonal) {
for (int i = 0; i < 4 * 4; ++i) {
elements[i] = 0;
}
for(int i = 0; i < 4; i += 1)
elements[i + i * 4] = diagonal;
}
mat4& mat4::mul(const mat4 &other) {
for (int i = 0; i < 4; ++i) // col
for (int j = 0; j < 4; ++j) { // row
float sum = 0;
for (int k = 0; k < 4; ++k)
sum += elements[j + k * 4] * other.elements[k + i * 4];
elements[j + i * 4] = sum;
}
return *this;
}
/*vec4 mat4::getColumn(int colIndex) {
//colIndex *= 4; // TODO: profile and see if it's the same as (colIndex * 4) in each cell
return vec4(elements[0 + colIndex * 4], elements[1 + colIndex * 4], elements[2 + colIndex * 4], elements[3 + colIndex * 4]);
}*/
mat4 mat4::identity() {
return mat4(1.0f);
}
mat4 operator*(mat4 left, const mat4 &right) {
return left.mul(right);
}
mat4 &mat4::operator*=(const mat4 &other) {
return mul(other);
}
mat4 mat4::orthographic(float left, float right, float bottom, float top, float near, float far) {
mat4 result(1);
result.elements[0 + 0 * 4] = 2.0f / (right - left);
result.elements[1 + 1 * 4] = 2.0f / (top - bottom);
result.elements[2 + 2 * 4] = -2.0f / (far - near);
result.elements[0 + 3 * 4] = (left + right) / (left - right);
result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
result.elements[2 + 3 * 4] = (far + near) / (far - near);
//result.elements[3 + 3 * 4] = 1; this is achieved by mat result(1);
return result;
}
mat4 mat4::perspective(float fov, float aspectRatio, float near, float far) {
mat4 result;
float q = 1.0f / tanf(toRadians(fov) / 2.0f);
result.elements[0 + 0 * 4] = q / aspectRatio;
result.elements[1 + 1 * 4] = q;
result.elements[2 + 2 * 4] = (near + far) / (near - far); // -(far + near) / (far - near);
result.elements[3 + 2 * 4] = -1;
result.elements[2 + 3 * 4] = 2 * far * near / (near - far); // -2 * far * near / (far - near);
return result;
}
mat4 mat4::translation(const vec3 &translation) {
mat4 result(1.0f); // identity matrix
result.elements[0 + 3 * 4] = translation.x; // create a matrix as follows: 1 0 0 x
result.elements[1 + 3 * 4] = translation.y; // 0 1 0 y
result.elements[2 + 3 * 4] = translation.z; // 0 0 1 z
return result; // 0 0 0 1
}
mat4 mat4::scale(const vec3 &scale) {
mat4 result(1.0f);
result.elements[0 + 0 * 4] = scale.x; // create a matrix as follows: x 0 0 0
result.elements[1 + 1 * 4] = scale.y; // 0 y 0 0
result.elements[2 + 2 * 4] = scale.z; // 0 0 z 0
return result; // 0 0 0 1
}
mat4 mat4::rotation(float angle, const vec3 &axis) {
mat4 result(1.0f);
float r = toRadians(angle);
float s = sinf(r);
float c = cosf(r);
result.elements[0 + 0 * 4] = axis.x * (1 - c) + c;
result.elements[1 + 0 * 4] = axis.x * axis.y * (1 - c) + axis.z * s;
result.elements[2 + 0 * 4] = axis.x * axis.z * (1 - c) - axis.y * s;
result.elements[0 + 1 * 4] = axis.y * axis.x * (1 - c) - axis.z * s;
result.elements[1 + 1 * 4] = axis.y * (1 - c) + c;
result.elements[2 + 1 * 4] = axis.y * axis.z * (1 - c) + axis.x * s;
result.elements[0 + 2 * 4] = axis.z * axis.x * (1 - c) + axis.y * s;
result.elements[1 + 2 * 4] = axis.z * axis.y * (1 - c) - axis.x * s;
result.elements[2 + 2 * 4] = axis.z * (1 - c) + c;
return result;
}
std::ostream &operator<<(std::ostream &stream, const mat4 &m) {
stream << "mat4: ( ";
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
stream << m.elements[i + j * 4] << " ";
}
if(i < 3) stream << std::endl << " ";
else stream << ")";
}
return stream;
}
我的vec4.h:
#include <iostream>
struct vec4 {
float w, x, y, z;
vec4() = default; // declare a default constructor as a no-parameter constructor (given that I have another one)
vec4(float w, float x, float y, float z);
vec4(const vec4 &v);
vec4 add(const vec4 &other);
vec4 add(float w, float x, float y, float z);
vec4 sub(const vec4 &other);
vec4 sub(float w, float x, float y, float z);
vec4 mul(const vec4 &other);
vec4 mul(float w, float x, float y, float z);
vec4 div(const vec4 &other);
vec4 div(float w, float x, float y, float z);
friend vec4 operator+(vec4 left, const vec4 &right);
friend vec4 operator-(vec4 left, const vec4 &right);
friend vec4 operator*(vec4 left, const vec4 &right);
friend vec4 operator/(vec4 left, const vec4 &right);
vec4 operator+=(const vec4 &other);
vec4 operator-=(const vec4 &other);
vec4 operator*=(const vec4 &other);
vec4 operator/=(const vec4 &other);
bool operator==(const vec4 &other);
bool operator!=(const vec4 &other);
friend std::ostream &operator<<(std::ostream &stream, const vec4 &vector);
};
我的vec4.cpp:
/* vec4::vec4() {
w = 0;
x = 0;
y = 0;
z = 0;
}
*/
vec4::vec4(float w, float x, float y, float z) {
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
vec4::vec4(const vec4 &v) {
this->w = v.w;
this->x = v.x;
this->y = v.y;
this->z = v.z;
}
vec4 vec4::add(const vec4 &other) {
this->w += other.w;
this->x += other.x;
this->y += other.y;
this->z += other.z;
return *this;
}
vec4 vec4::add(float w, float x, float y, float z) {
this->w += w;
this->x += x;
this->y += y;
this->z += z;
return *this;
}
vec4 vec4::sub(const vec4 &other) {
this->w -= other.w;
this->x -= other.x;
this->y -= other.y;
this->z -= other.z;
return *this;
}
vec4 vec4::sub(float w, float x, float y, float z) {
this->w -= w;
this->x -= x;
this->y -= y;
this->z -= z;
return *this;
}
vec4 vec4::mul(const vec4 &other) {
this->w *= other.w;
this->x *= other.x;
this->y *= other.y;
this->z *= other.z;
return *this;
}
vec4 vec4::mul(float w, float x, float y, float z) {
this->w *= w;
this->x *= x;
this->y *= y;
this->z *= z;
return *this;
}
vec4 vec4::div(const vec4 &other) {
this->w /= other.w;
this->x /= other.x;
this->y /= other.y;
this->z /= other.z;
return *this;
}
vec4 vec4::div(float w, float x, float y, float z) {
this->w /= w;
this->x /= x;
this->y /= y;
this->z /= z;
return *this;
}
std::ostream &operator<<(std::ostream &stream, const vec4 &vector) {
stream << "vec4: (" << vector.w << ", " << vector.x << ", " << vector.y << ", " << vector.z << ")";
return stream;
}
vec4 operator+(vec4 left, const vec4 &right) {
return left.add(right);
}
vec4 operator-(vec4 left, const vec4 &right) {
return left.sub(right);
}
vec4 operator*(vec4 left, const vec4 &right) {
return left.mul(right);
}
vec4 operator/(vec4 left, const vec4 &right) {
return left.div(right);
}
vec4 vec4::operator+=(const vec4 &other) {
return add(other);
}
vec4 vec4::operator-=(const vec4 &other) {
return sub(other);
}
vec4 vec4::operator*=(const vec4 &other) {
return mul(other);
}
vec4 vec4::operator/=(const vec4 &other) {
return div(other);
}
bool vec4::operator==(const vec4 &other) {
return (this->w == other.w && this->x == other.x && this->y == other.y && this->z == other.z);
}
bool vec4::operator!=(const vec4 &other) {
return !(*this == other);
}
以及错误日志:
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::identity()’:
.../src/math/mat4.cpp:36:29: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return mat4(1.0f);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(engine::math::mat4&&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
.../src/math/mat4.cpp: In function ‘engine::math::mat4 engine::math::operator*(engine::math::mat4, const engine::math::mat4&)’:
.../src/math/mat4.cpp:40:34: error: use of deleted function ‘engine::math::mat4::mat4(const engine::math::mat4&)’
return left.mul(right);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(const engine::math::mat4&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::orthographic(float, float, float, float, float, float)’:
.../src/math/mat4.cpp:56:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::perspective(float, float, float, float)’:
.../src/math/mat4.cpp:69:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::translation(const engine::math::vec3&)’:
.../src/math/mat4.cpp:77:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result; // 0 0 0 1
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::scale(const engine::math::vec3&)’:
.../src/math/mat4.cpp:85:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result; // 0 0 0 1
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::rotation(float, const engine::math::vec3&)’:
.../src/math/mat4.cpp:105:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
CMakeFiles/GameEngine.dir/build.make:169: recipe for target 'CMakeFiles/GameEngine.dir/src/math/mat4.cpp.o' failed
make[3]: *** [CMakeFiles/GameEngine.dir/src/math/mat4.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
.../main.cpp: In function ‘int main(int, char**)’:
.../main.cpp:19:50: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
mat4 position = mat4::translation(vec3(2,3,4));
^
In file included from .../src/math/math.h:8:0,
from .../main.cpp:4:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(engine::math::mat4&&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
我假设大部分代码都是无关紧要的,所以不要费心阅读所有代码。
只是为了比较,如果我从 mat4.h 的联合中删除 link vec4 columns[4];
,那么一切都很棒。
在过去的一个小时里,我一直在为此伤脑筋,所以我真的需要一些帮助。
谢谢。
编辑:
在尝试了@0x499602D2 的建议并将 mat4(mat4&&) = default;
添加到 mat4.h 之后,我只剩下一个错误:
.../src/math/mat4.cpp: In function ‘engine::math::mat4 engine::math::operator*(engine::math::mat4, const engine::math::mat4&)’:
.../src/math/mat4.cpp:39:34: error: use of deleted function ‘engine::math::mat4::mat4(const engine::math::mat4&)’
return left.mul(right);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(const engine::math::mat4&)’ is implicitly declared as deleted because ‘engine::math::mat4’ declares a move constructor or move assignment operator
struct mat4 {
^
我该怎么做才能解决这个问题?
vec4
声明了一个复制构造函数,因此没有为其 class 生成的隐式移动构造函数。因为你的联合中有一个 vec4
数组,它的移动构造函数被删除,因为 vec4
不能被移动。此外,由于 vec4
有一个用户提供的复制构造函数,它被认为是重要的,因此联合的复制构造函数也被删除了。由于联合是 mat4
的成员(并且联合有一个已删除的副本和移动构造函数)mat4
的副本和移动构造函数也被删除。
已删除的函数在重载决策中仍然发挥作用,因此选择已删除的移动构造函数,因为您正在从临时文件初始化 return 值。要解决此问题,请在 vec4
:
内声明一个默认移动构造函数
struct vec4 {
// ...
vec4(vec4&&) = default;
// ...
};
和mat4
中的复制构造函数:
mat4(mat4 const&) {}
如果您有任何成员需要复制,您必须手动复制 AFAIK。
0x499602D2 的回答解释了您的错误并回答了您提出的具体问题。但我认为以两种可能的方式存储矩阵数据至少是一种奇怪的设计。而且您的实现与它不一致,因为在 mat4& mat4::mul(const mat4 &other)
(和其他方法)中您只使用联合的 elements
部分。
恕我直言,您应该考虑:
- 用简单的
float elements[4 * 4];
替换并集
- 添加一个带有 4 个
vec4
参数并将值存储到 elements
数组中的构造函数
- 添加一个 const 方法从矩阵中提取向量
因为定义一个内部实现和任意多的外部 表示更为常见。
它没有直接回答你的问题(@0x499602D2 已经回答了),但如果你遵循这个建议,问题就会消失,所以这个答案......
我正在尝试制作一个 4*4 矩阵的 class,它是由 16 个浮点数组成的数组构建的,但我也想将它表示为 4 个 vec4 的数组(对于每个柱子)。
问题是它没有编译,并且在我调用 mat4 的构造函数的任何地方都会出错。
我的 mat4.h:
struct mat4 {
union
{
float elements[4 * 4]; // column major ordering, index = row + col * 4
vec4 columns[4];
};
mat4();
mat4(float diagonal);
mat4& mul(const mat4& other); //TODO: maybe return mat4
// vec4 getColumn(int colIndex);
static mat4 identity(); // construct and return an identity matrix
static mat4 orthographic(float left, float right, float bottom, float top, float near, float far); // boundaries (clipping planes)
static mat4 perspective(float fov, float aspectRatio, float near, float far);
static mat4 translation(const vec3& translation);
static mat4 scale(const vec3 &scale);
static mat4 rotation(float angle, const vec3 & axis);
friend mat4 operator*(mat4 left, const mat4 & right);
mat4& operator*=(const mat4 &other); //TODO: check that it fits with the vectors
friend std::ostream &operator<<(std::ostream &stream, const mat4 &m);
};
我的mat4.cpp:
#include "mat4.h"
mat4::mat4() {
for (int i = 0; i < 4 * 4; i++)
elements[i] = 0;
}
mat4::mat4(float diagonal) {
for (int i = 0; i < 4 * 4; ++i) {
elements[i] = 0;
}
for(int i = 0; i < 4; i += 1)
elements[i + i * 4] = diagonal;
}
mat4& mat4::mul(const mat4 &other) {
for (int i = 0; i < 4; ++i) // col
for (int j = 0; j < 4; ++j) { // row
float sum = 0;
for (int k = 0; k < 4; ++k)
sum += elements[j + k * 4] * other.elements[k + i * 4];
elements[j + i * 4] = sum;
}
return *this;
}
/*vec4 mat4::getColumn(int colIndex) {
//colIndex *= 4; // TODO: profile and see if it's the same as (colIndex * 4) in each cell
return vec4(elements[0 + colIndex * 4], elements[1 + colIndex * 4], elements[2 + colIndex * 4], elements[3 + colIndex * 4]);
}*/
mat4 mat4::identity() {
return mat4(1.0f);
}
mat4 operator*(mat4 left, const mat4 &right) {
return left.mul(right);
}
mat4 &mat4::operator*=(const mat4 &other) {
return mul(other);
}
mat4 mat4::orthographic(float left, float right, float bottom, float top, float near, float far) {
mat4 result(1);
result.elements[0 + 0 * 4] = 2.0f / (right - left);
result.elements[1 + 1 * 4] = 2.0f / (top - bottom);
result.elements[2 + 2 * 4] = -2.0f / (far - near);
result.elements[0 + 3 * 4] = (left + right) / (left - right);
result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
result.elements[2 + 3 * 4] = (far + near) / (far - near);
//result.elements[3 + 3 * 4] = 1; this is achieved by mat result(1);
return result;
}
mat4 mat4::perspective(float fov, float aspectRatio, float near, float far) {
mat4 result;
float q = 1.0f / tanf(toRadians(fov) / 2.0f);
result.elements[0 + 0 * 4] = q / aspectRatio;
result.elements[1 + 1 * 4] = q;
result.elements[2 + 2 * 4] = (near + far) / (near - far); // -(far + near) / (far - near);
result.elements[3 + 2 * 4] = -1;
result.elements[2 + 3 * 4] = 2 * far * near / (near - far); // -2 * far * near / (far - near);
return result;
}
mat4 mat4::translation(const vec3 &translation) {
mat4 result(1.0f); // identity matrix
result.elements[0 + 3 * 4] = translation.x; // create a matrix as follows: 1 0 0 x
result.elements[1 + 3 * 4] = translation.y; // 0 1 0 y
result.elements[2 + 3 * 4] = translation.z; // 0 0 1 z
return result; // 0 0 0 1
}
mat4 mat4::scale(const vec3 &scale) {
mat4 result(1.0f);
result.elements[0 + 0 * 4] = scale.x; // create a matrix as follows: x 0 0 0
result.elements[1 + 1 * 4] = scale.y; // 0 y 0 0
result.elements[2 + 2 * 4] = scale.z; // 0 0 z 0
return result; // 0 0 0 1
}
mat4 mat4::rotation(float angle, const vec3 &axis) {
mat4 result(1.0f);
float r = toRadians(angle);
float s = sinf(r);
float c = cosf(r);
result.elements[0 + 0 * 4] = axis.x * (1 - c) + c;
result.elements[1 + 0 * 4] = axis.x * axis.y * (1 - c) + axis.z * s;
result.elements[2 + 0 * 4] = axis.x * axis.z * (1 - c) - axis.y * s;
result.elements[0 + 1 * 4] = axis.y * axis.x * (1 - c) - axis.z * s;
result.elements[1 + 1 * 4] = axis.y * (1 - c) + c;
result.elements[2 + 1 * 4] = axis.y * axis.z * (1 - c) + axis.x * s;
result.elements[0 + 2 * 4] = axis.z * axis.x * (1 - c) + axis.y * s;
result.elements[1 + 2 * 4] = axis.z * axis.y * (1 - c) - axis.x * s;
result.elements[2 + 2 * 4] = axis.z * (1 - c) + c;
return result;
}
std::ostream &operator<<(std::ostream &stream, const mat4 &m) {
stream << "mat4: ( ";
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
stream << m.elements[i + j * 4] << " ";
}
if(i < 3) stream << std::endl << " ";
else stream << ")";
}
return stream;
}
我的vec4.h:
#include <iostream>
struct vec4 {
float w, x, y, z;
vec4() = default; // declare a default constructor as a no-parameter constructor (given that I have another one)
vec4(float w, float x, float y, float z);
vec4(const vec4 &v);
vec4 add(const vec4 &other);
vec4 add(float w, float x, float y, float z);
vec4 sub(const vec4 &other);
vec4 sub(float w, float x, float y, float z);
vec4 mul(const vec4 &other);
vec4 mul(float w, float x, float y, float z);
vec4 div(const vec4 &other);
vec4 div(float w, float x, float y, float z);
friend vec4 operator+(vec4 left, const vec4 &right);
friend vec4 operator-(vec4 left, const vec4 &right);
friend vec4 operator*(vec4 left, const vec4 &right);
friend vec4 operator/(vec4 left, const vec4 &right);
vec4 operator+=(const vec4 &other);
vec4 operator-=(const vec4 &other);
vec4 operator*=(const vec4 &other);
vec4 operator/=(const vec4 &other);
bool operator==(const vec4 &other);
bool operator!=(const vec4 &other);
friend std::ostream &operator<<(std::ostream &stream, const vec4 &vector);
};
我的vec4.cpp:
/* vec4::vec4() {
w = 0;
x = 0;
y = 0;
z = 0;
}
*/
vec4::vec4(float w, float x, float y, float z) {
this->w = w;
this->x = x;
this->y = y;
this->z = z;
}
vec4::vec4(const vec4 &v) {
this->w = v.w;
this->x = v.x;
this->y = v.y;
this->z = v.z;
}
vec4 vec4::add(const vec4 &other) {
this->w += other.w;
this->x += other.x;
this->y += other.y;
this->z += other.z;
return *this;
}
vec4 vec4::add(float w, float x, float y, float z) {
this->w += w;
this->x += x;
this->y += y;
this->z += z;
return *this;
}
vec4 vec4::sub(const vec4 &other) {
this->w -= other.w;
this->x -= other.x;
this->y -= other.y;
this->z -= other.z;
return *this;
}
vec4 vec4::sub(float w, float x, float y, float z) {
this->w -= w;
this->x -= x;
this->y -= y;
this->z -= z;
return *this;
}
vec4 vec4::mul(const vec4 &other) {
this->w *= other.w;
this->x *= other.x;
this->y *= other.y;
this->z *= other.z;
return *this;
}
vec4 vec4::mul(float w, float x, float y, float z) {
this->w *= w;
this->x *= x;
this->y *= y;
this->z *= z;
return *this;
}
vec4 vec4::div(const vec4 &other) {
this->w /= other.w;
this->x /= other.x;
this->y /= other.y;
this->z /= other.z;
return *this;
}
vec4 vec4::div(float w, float x, float y, float z) {
this->w /= w;
this->x /= x;
this->y /= y;
this->z /= z;
return *this;
}
std::ostream &operator<<(std::ostream &stream, const vec4 &vector) {
stream << "vec4: (" << vector.w << ", " << vector.x << ", " << vector.y << ", " << vector.z << ")";
return stream;
}
vec4 operator+(vec4 left, const vec4 &right) {
return left.add(right);
}
vec4 operator-(vec4 left, const vec4 &right) {
return left.sub(right);
}
vec4 operator*(vec4 left, const vec4 &right) {
return left.mul(right);
}
vec4 operator/(vec4 left, const vec4 &right) {
return left.div(right);
}
vec4 vec4::operator+=(const vec4 &other) {
return add(other);
}
vec4 vec4::operator-=(const vec4 &other) {
return sub(other);
}
vec4 vec4::operator*=(const vec4 &other) {
return mul(other);
}
vec4 vec4::operator/=(const vec4 &other) {
return div(other);
}
bool vec4::operator==(const vec4 &other) {
return (this->w == other.w && this->x == other.x && this->y == other.y && this->z == other.z);
}
bool vec4::operator!=(const vec4 &other) {
return !(*this == other);
}
以及错误日志:
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::identity()’:
.../src/math/mat4.cpp:36:29: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return mat4(1.0f);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(engine::math::mat4&&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
.../src/math/mat4.cpp: In function ‘engine::math::mat4 engine::math::operator*(engine::math::mat4, const engine::math::mat4&)’:
.../src/math/mat4.cpp:40:34: error: use of deleted function ‘engine::math::mat4::mat4(const engine::math::mat4&)’
return left.mul(right);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(const engine::math::mat4&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::orthographic(float, float, float, float, float, float)’:
.../src/math/mat4.cpp:56:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::perspective(float, float, float, float)’:
.../src/math/mat4.cpp:69:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::translation(const engine::math::vec3&)’:
.../src/math/mat4.cpp:77:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result; // 0 0 0 1
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::scale(const engine::math::vec3&)’:
.../src/math/mat4.cpp:85:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result; // 0 0 0 1
^
.../src/math/mat4.cpp: In static member function ‘static engine::math::mat4 engine::math::mat4::rotation(float, const engine::math::vec3&)’:
.../src/math/mat4.cpp:105:20: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
return result;
^
CMakeFiles/GameEngine.dir/build.make:169: recipe for target 'CMakeFiles/GameEngine.dir/src/math/mat4.cpp.o' failed
make[3]: *** [CMakeFiles/GameEngine.dir/src/math/mat4.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
.../main.cpp: In function ‘int main(int, char**)’:
.../main.cpp:19:50: error: use of deleted function ‘engine::math::mat4::mat4(engine::math::mat4&&)’
mat4 position = mat4::translation(vec3(2,3,4));
^
In file included from .../src/math/math.h:8:0,
from .../main.cpp:4:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(engine::math::mat4&&)’ is implicitly deleted because the default definition would be ill-formed:
struct mat4 {
^
.../src/math/mat4.h:16:31: error: union member ‘engine::math::mat4::<anonymous union>::columns’ with non-trivial ‘engine::math::vec4::vec4(const engine::math::vec4&)’
vec4 columns[4];
^
我假设大部分代码都是无关紧要的,所以不要费心阅读所有代码。
只是为了比较,如果我从 mat4.h 的联合中删除 link vec4 columns[4];
,那么一切都很棒。
在过去的一个小时里,我一直在为此伤脑筋,所以我真的需要一些帮助。
谢谢。
编辑:
在尝试了@0x499602D2 的建议并将 mat4(mat4&&) = default;
添加到 mat4.h 之后,我只剩下一个错误:
.../src/math/mat4.cpp: In function ‘engine::math::mat4 engine::math::operator*(engine::math::mat4, const engine::math::mat4&)’:
.../src/math/mat4.cpp:39:34: error: use of deleted function ‘engine::math::mat4::mat4(const engine::math::mat4&)’
return left.mul(right);
^
In file included from .../src/math/mat4.cpp:5:0:
.../src/math/mat4.h:11:16: note: ‘engine::math::mat4::mat4(const engine::math::mat4&)’ is implicitly declared as deleted because ‘engine::math::mat4’ declares a move constructor or move assignment operator
struct mat4 {
^
我该怎么做才能解决这个问题?
vec4
声明了一个复制构造函数,因此没有为其 class 生成的隐式移动构造函数。因为你的联合中有一个 vec4
数组,它的移动构造函数被删除,因为 vec4
不能被移动。此外,由于 vec4
有一个用户提供的复制构造函数,它被认为是重要的,因此联合的复制构造函数也被删除了。由于联合是 mat4
的成员(并且联合有一个已删除的副本和移动构造函数)mat4
的副本和移动构造函数也被删除。
已删除的函数在重载决策中仍然发挥作用,因此选择已删除的移动构造函数,因为您正在从临时文件初始化 return 值。要解决此问题,请在 vec4
:
struct vec4 {
// ...
vec4(vec4&&) = default;
// ...
};
和mat4
中的复制构造函数:
mat4(mat4 const&) {}
如果您有任何成员需要复制,您必须手动复制 AFAIK。
0x499602D2 的回答解释了您的错误并回答了您提出的具体问题。但我认为以两种可能的方式存储矩阵数据至少是一种奇怪的设计。而且您的实现与它不一致,因为在 mat4& mat4::mul(const mat4 &other)
(和其他方法)中您只使用联合的 elements
部分。
恕我直言,您应该考虑:
- 用简单的
float elements[4 * 4];
替换并集
- 添加一个带有 4 个
vec4
参数并将值存储到elements
数组中的构造函数 - 添加一个 const 方法从矩阵中提取向量
因为定义一个内部实现和任意多的外部 表示更为常见。
它没有直接回答你的问题(@0x499602D2 已经回答了),但如果你遵循这个建议,问题就会消失,所以这个答案......