我尝试定义一个基于模板的vector类,但得到此警告消息
warning: definition of implicit copy constructor for 'Vec<double, 3>' is deprecated because it has a user-provided copy assignment operator [-Wdeprecated-copy-with-user-provided-copy]
Vec &operator=(const Vec &t)
^
...test_temp.cpp:86:17: note: in implicit copy constructor for 'Vec<double, 3>' first required here
auto vadd = v1 + v2;
^
1 warning generated.
我不知道这里有什么好的做法。我应该把赋值操作符标记为默认值,还是只添加-Wno-deprecated-copy-with-user-provided-copy
?是否有其他解决方案来解决这个问题?
这是一个测试文件:
#include <iostream>
#include <assert.h>
template <typename T, uint Size>
class Vec
{
public:
static const int NUM_COMPONENTS = Size;
T Components[NUM_COMPONENTS];
Vec() {}
Vec(T init)
{
for (uint i = 0; i < this->NUM_COMPONENTS; i++)
{
this->Components[i] = init;
}
}
Vec<T,Size> operator+(const Vec &t) const
{
assert(this->NUM_COMPONENTS == t.NUM_COMPONENTS);
Vec<T,Size> result;
for (uint i = 0; i < this->NUM_COMPONENTS; i++)
{
result[i] = this->Components[i] + t.Components[i];
}
return result;
}
Vec<T,Size> operator-(const Vec &t) const
{
assert(this->NUM_COMPONENTS == t.NUM_COMPONENTS);
Vec<T,Size> result;
for (uint i = 0; i < this->NUM_COMPONENTS; i++)
{
result[i] = this->Components[i] - t.Components[i];
}
return result;
}
T &operator[](uint index)
{
assert(index >= 0);
assert(index < this->NUM_COMPONENTS);
return this->Components[index];
}
const T &operator[](uint index) const
{
assert(index >= 0);
assert(index < this->NUM_COMPONENTS);
return this->Components[index];
}
Vec<T,Size> &operator=(const Vec<T,Size> &t)
{
assert(this->NUM_COMPONENTS == t.NUM_COMPONENTS);
for (uint i = 0; i < this->NUM_COMPONENTS; i++)
{
this->Components[i] = t.Components[i];
}
return *this;
}
void Show()
{
for (int i = 0; i < this->NUM_COMPONENTS; i++)
{
printf("%lf ", 1.0 * this->Components[i]);
}
printf("\n");
}
};
int main() {
Vec<double, 3> v1;
for (int i = 0; i < 3; i++)
{
v1[i] = 2.0;
}
Vec<double, 3> v2;
for (int i = 0; i < 3; i++)
{
v2[i] = 3.0;
}
auto vadd = v1 + v2;
std::cout << "test";
vadd.Show();
return 0;
}
设置cmake flag为:
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic")
非常感谢您的帮助!
2条答案
按热度按时间3lxsmp7m1#
你根本不应该声明复制赋值操作符。隐式定义的一个确实已经做了你想要的。
在以下情况下,始终遵循零法则:不要声明析构函数、复制/移动构造函数或复制/移动赋值运算符。如果你确实需要它们中的任何一个,那么就遵循三/五规则,并定义它们中的所有,因为如果是这样的话,你几乎肯定也需要它们中的自定义行为。
这是C++类设计中最重要的规则。不幸的是,语言本身并没有强制执行它。然而,当复制赋值运算符已经由用户声明时,复制构造函数的隐式声明已被弃用,以支持该规则。这就是编译器警告你的。
解决方案是 * 不 * 添加一个复制构造函数。将其定义为与编译器将生成的代码完全相同总是会导致更差的代码。
0s7z1bwu2#
我刚刚发现添加一个复制构造函数(我忘记添加了)可以解决这个问题,只需在这里发布一个潜在的答案: