如果参数是可复制构造的,我希望调用一个函数和另一个函数(类似于前面的但有额外的代码)。我发现 std::is_copy_constructible 没有按预期工作
#include <iostream>
using namespace std;
struct NoCopy {
int n;
NoCopy(const NoCopy&) = delete;
};
template <typename T,
typename U,
std::enable_if_t<!std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
std::cout<<"\n"<<typeid(U).name()<<" does not have copy constructor; ";
}
template <typename T,
typename U,
std::enable_if_t<std::is_copy_constructible_v<U>, int> = 0>
void log_debug(T&& t, U&& u)
{
std::cout<<"\n"<<typeid(U).name()<<" has copy constructor; ";
}
int main()
{
NoCopy a{2};
log_debug("value is ", a);
std::cout<<"\nstd::is_nothrow_copy_constructible_v "<<std::is_copy_constructible_v<NoCopy>; //returns 0 as expected
return 0;
} …Run Code Online (Sandbox Code Playgroud) 我正在使用 VS Code 在 Linux 中使用 g++ 进行编译和调试。
需要包括和使用:
#include <string>
#include <iostream>
using namespace std;
Run Code Online (Sandbox Code Playgroud)
这是我的类是可移动的:
class A {
public:
A(const string& strA) : strA(strA) {}
A(const A& a) : A(a.strA) {
}
A(A&& a) : A(a.strA) {
a.strA = "";
}
string strA;
};
Run Code Online (Sandbox Code Playgroud)
返回 A 实例的示例函数:
A RetA() {
A a("a");
A b("bha");
string ex;
cin >> ex;
a.strA += ex;
return ex == "123" ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
这是简单的主要内容:
int main() {
A a(RetA());
return …Run Code Online (Sandbox Code Playgroud) 我们知道内置数组既不能复制也不能赋值。因此,如果它是类/结构/联合的成员数据,则可以让编译器发挥其魔力来复制它们:
struct ArrInt5{
ArrInt5() = default;
ArrInt5(ArrInt5 const&) = default; // OK
int a[5];
};
ArrInt5 a, b = a; // OK
Run Code Online (Sandbox Code Playgroud)
有时情况并非如此,例如,如果数组包含非默认可构造对象的对象。在这种情况下,我们确实需要定义复制因子来完成这项工作:
struct Bar{
// deleted default ctor
Bar(int x) : x_(x){}
int x_ = 0;
};
struct Foo{
Foo();
Foo(Foo const&);
Bar arr_[5];
};
Foo::Foo() : arr_{0, 1, 2, 3, 4}
{}
Foo::Foo(Foo const& rhs) : arr_{rhs.arr_[0], rhs.arr_[1], rhs.arr_[2], rhs.arr_[3], rhs.arr_[4]}
{}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,Foo有一个由五个类型的对象组成的内置数组,struct Bar该类型不可默认构造,因此默认构造函数和复制构造函数必须对其进行初始化(arr_)。
问题是:如果数组很大(比如 100 万个元素),如何初始化该数组?我应该逐个元素地硬复制它们吗?或者有一些解决方法?
std::array但我不讨论这个主题,我想问是否有针对我的内置非默认可构造对象数组的解决方法。假设我有这个代码:
void MyFunc(const std::string& param) {
std::string maybe_altered_param;
if (ConditionIsMet()) {
maybe_altered_param = AlterParam(param);
} else {
maybe_altered_param = param; // <-- unnecessary copy
}
// do stuff with maybe_altered_param
// maybe_altered_param does not need to be modified further.
}
Run Code Online (Sandbox Code Playgroud)
该AlterParam函数返回字符串的副本,因此当ConditionIsMet返回 true 时,会创建一个副本以填充 Maybe_altered_param。然而,当ConditionIsMet(),这是次优的。在第二种情况下,我只想为同一个对象指定另一个名称,而不需要副本或任何类似的内容。
在这种情况下删除不必要的副本的最简单方法是什么?
我有以下 C++ 代码。您可以看到我创建了一个带有构造函数和复制构造函数的结构。有人可以解释一下为什么为第一个赋值调用复制构造函数而不是为其他 2 个赋值调用吗?
#include <iostream>
#include <string>
#include <vector>
struct Vertex
{
float x, y, z;
Vertex(float x, float y, float z)
: x(x), y(y), z(z)
{
std::cout << "Created Vertex!" << std::endl;
}
Vertex(const Vertex& v) // Copy constructor
: x(v.x), y(v.y), z(v.z)
{
std::cout << "Copied!" << std::endl;
}
};
std::ostream& operator<<(std::ostream& stream, const Vertex& _v) // Overloading operator<<
{
stream << _v.x << ", " << _v.y << ", " << _v.z;
return stream;
} …Run Code Online (Sandbox Code Playgroud) 我在 C 项目中的头文件中有一个结构。
struct tgMethod {
const char *name;
const enum tgAccessModifier access;
const enum tgMethodKind kind;
tgTypeRef return_type;
const tgParams params;
const tgMethod *overrides;
const void *userptr;
const tgObject *(*methodptr)(tgObject *, size_t, tgObject *, void *);
};
Run Code Online (Sandbox Code Playgroud)
在链接这个 C 项目的 C++ 项目中,我有这个结构,它使用 asEntryAllocator<tgMethod>但编译器给出错误:error C2280: "tgMethod &tgMethod::operator =(const tgMethod &)": attempting to reference a deleted function
template<typename T>
struct EntryAllocator {
public:
EntryAllocator() : EntryAllocator(1 << 7) { }
explicit EntryAllocator(size_t max_size) :
_start(0), _count(0), _capacity(max_size), _data((T*)calloc(max_size, …Run Code Online (Sandbox Code Playgroud) (和cpp失去联系太久了,想复习一下明天的面试)。
正在修订深层复制与浅层复制。写了代码:
#include <iostream>
class MyClass {
public:
unsigned int* uivar = nullptr;
MyClass() : uivar(new unsigned int) {
*(this->uivar) = 3;
}
~MyClass() { delete uivar; }
MyClass(const MyClass& mCopy) {
*(uivar) = *(mCopy.uivar);
}
};
void function(MyClass m) {
*(m.uivar) = 4;
}
int main() {
MyClass myClass;
MyClass myClassCopy = myClass;
std::cout << *(myClass.uivar) << "\n";
std::cout << *(myClassCopy.uivar) << "\n";
function(myClass);
std::cout << *(myClass.uivar) << "\n";
std::cout << "hhhh" << "\n";
*(myClassCopy.uivar) = 5;
std::cout << …Run Code Online (Sandbox Code Playgroud) 比方说,我们想要反转一个数组,就像这个函数一样。
对于两个元素的每次交换,都会进行复制构造函数、析构函数和两个复制赋值。
template<class T>
void Reverse(T *arr, int size)
{
T *leftItem = arr;
T *rightItem = &arr[size - 1];
for (int i = 0; i < size / 2; i++, leftItem++, rightItem--)
{
T swap = *leftItem; // Copy constructor
*leftItem = *rightItem; // Copy assignment
*rightItem = swap; // Copy assignment
} // Destructor
}
Run Code Online (Sandbox Code Playgroud)
这看起来很可怕。所以我想出了一个想法,但我不确定它是好还是坏,因为我实际上在这里安全地绕过了所有类型和约定。
但另一方面,它避免了复制操作,根据类型的不同,复制操作可能会很繁重。
template<class T>
void ReverseUsingMemcpy(T *arr, int size)
{
char *swap = new char[sizeof(T)];
T …Run Code Online (Sandbox Code Playgroud) 我们都知道隐式复制构造函数的操作如下:默认构造所有成员变量,然后为每个成员变量分配适当的相应值.
我经常需要一个复制构造函数,它将 每个成员变量初始化为副本,而不是默认构造然后分配.(例如,我有一些const成员变量).
问题: 手动编写一个复制构造函数,将每个成员变量初始化为副本非常繁琐,并且随着成员变量数量的增加而变得荒谬可笑.有没有办法让隐式复制构造函数使用初始化列表?有没有其他方法可以手动编写初始化列表?
我不明白为什么他们没有一个复制构造函数,该复制构造函数可以使原始整数倍。
众所周知,默认拷贝构造函数的主要问题是执行浅拷贝。这样,如果有一个指针,它只会复制它的地址,但是为什么不取消引用该指针而复制内容呢?当动态分配内存时会出现主要问题。因此,在有指向它的指针的情况下可以错误地删除它,这就是为什么我们要创建自己的副本构造函数而不使用默认的构造函数的原因。
但是我不明白,为什么CPP不这样做?为什么不复制内容
c++ ×10
copy-constructor ×10
constructor ×2
arrays ×1
c++17 ×1
class ×1
deep-copy ×1
move ×1
shallow-copy ×1
struct ×1
templates ×1