我正在處理一個 C 專案,我需要做一些分配代碼來將一個物件分配給另一個具有不同型別的物件,如下所示:
MyClass1 o1;
MyClass2 o2;
o2 = o1;
MyClass2Ofc,我們可以在:的復制賦值運算子的幫助下完成這項作業MyClass2& operator=(const MyClass1&)。
但這對我來說將是一項非常繁重的作業,因為已經有成千上萬的課程需要完成類似的作業o2 = o1。我不想為它們中的每一個一個一個地添加一個復制賦值運算子......
我在想是否有其他方法,比如一些 TMP 方法來幫助我......
我可以確保具有完全相同的資料成員和相同的宣告順序(見下文)MyClass1。MyClass2如果是這樣,是否有一些 TMP 方法可以幫助我?
struct MyClass1 {
int a;
char ch;
std::string msg;
// some virtual member functions
};
struct MyClass2 {
int a;
char ch;
std::string msg;
// some virtual member functions
};
順便說一句,您可能想問為什么有這樣兩個具有相同資料成員的類/結構。好吧,這是出于某種歷史原因,我無法將它們融合到一個類/結構中。
更新
看來我沒有把我的問題說清楚。我會在這里做一個例子。
void doJob(const MyClass1& o1) {}
void func1(MyClass1 o1) {
doJob(o1);
}
void func2(MyClass2 o2) {
MyClass o1;
o1.? = o2.?; // assign each element of o2 to o1.
doJob(o1);
}
這是真實的情況。如您所見,o1.? = o2.?包含多行,這取決于 MyClass1/MyClass2 的資料成員數。我試圖找到一些方法來避免在func2.
另外,正如我所說,我有數千個類,例如 MyClass1/MyClass2,這意味著這些類具有完全不同的資料成員。
所以對于 MyClass1 和 MyClass2,o1.? = o2.?是o1.a = o2.a; o1.ch = o2.ch; o1.msg = o2.msg;但是對于其他類,它可能會變成o1.f = o2.f; o1.vec = o2.vec;. 這就是為什么我認為我可能需要一些 TMP 技術......
更新2
Alice developed the classes:
struct MyClass1 {// data members};
struct MyClass2 {// data members};
// MyClass1 and MyClass2 have exactly the same data members and declaration order
struct MyClass3 {// data members};
struct MyClass4 {// data members};
// MyClass3 and MyClass4 have exactly the same data members and declaration order
...
...
struct MyClass1000 {// data members};
struct MyClass1001 {// data members};
// MyClass1000 and MyClass1001 have exactly the same data members and declaration order
I'm developing the functions:
void doJob1(const MyClass1& o1) {}
void func1(MyClass1 o1) {
doJob(o1);
}
void func2(MyClass2 o2) {
MyClass1 o1;
o1.? = o2.?; // assign each element of o2 to o1.
doJob1(o1);
}
...
...
void doJob1000(const MyClass1000& o1) {}
void func1000(MyClass1000 o1) {
doJob1000(o1);
}
void func1001(MyClass1001 o2) {
MyClass1000 o1;
o1.? = o2.?; // assign each element of o2 to o1.
doJob1000(o1);
}
Why did Alice do such a stupid design? For some historical reason...
Why not using std::memcpy? Because these classes contain virtual functions.
uj5u.com熱心網友回復:
是的,你可以......但我不建議這樣做,除非這兩個類具有完全相同的一一對應關系并且在您的問題領域中具有完全相同的含義。
為什么不推薦?
- 因為操作需要手動實作(編譯器無法幫助
= default宣告)。
auto operator=(MyClass1 const& other) -> MyClass2& {
std::tie(a, ch, msg) = std::tie(other.a, other.ch, other.msg);
return *this;
}
- 因為如果你定義了賦值,你最終將需要在兩個方向上定義相等 (
==) 和不相等 ( )。!=否則,這些類將不符合邏輯。
bool operator==(MyClass1 const& mc1, MyClass2 const& mc2) {
return std::tie(mc1.a, mc1.ch, mc1.msg) == std::tie(mc2.a, mc2.ch, mc2.msg);
}
bool operator==(MyClass2 const& mc2, MyClass1 const& mc1) {
return std::tie(mc1.a, mc1.ch, mc1.msg) == std::tie(mc2.a, mc2.ch, mc2.msg);
}
bool operator!=(MyClass1 const& mc1, MyClass2 const& mc2) {
return std::tie(mc1.a, mc1.ch, mc1.msg) != std::tie(mc2.a, mc2.ch, mc2.msg);
}
bool operator!=(MyClass2 const& mc2, MyClass1 const& mc1) {
return std::tie(mc1.a, mc1.ch, mc1.msg) != std::tie(mc2.a, mc2.ch, mc2.msg);
}
- 因為如果您定義賦值,您將定義一個建構式或從一個到另一個的轉換。
/*explicit?*/ operator MyClass1() const& {return {a, ch, msg};} // need thios
- 和一個移動建構式?
/*explicit?*/ operator MyClass1() && {return {a, ch, std::move(msg)};} // need this
- 如果一個也可以訂購另一個,并且您需要在兩個類之間定義兩個方向的順序
// won't even try
// bool operator<
// bool operator<=
// bool operator>
// bool operator>=
// bool operator<
// bool operator<=
// bool operator>
// bool operator>=
and for that matter any function that work with one should work with the other, because well, when you assign you are saying that two things are logical equal among other tings.
full code here: https://godbolt.org/z/c8d34eT48
While it seems to be your case (albeit a very suspicious case), as you see, you open a Pandora's box by defining equality between two classes.
Just by calling the "assignment" convert instead you save your self a big headache. Don't use operator=. My recommended code is to just use another name:
MyClass2& convert(MyClass1 const& from, MyClass2& to) {
std::tie(to.a, to.ch, to.msg) = std::tie(from.a, from.ch, from.msg);
return to;
}
MyClass2& convert(MyClass1&& from, MyClass2& to) {
std::tie(to.a, to.ch, to.msg) = std::tie(from.a, from.ch, std::move(from.msg));
return to;
}
More material: https://www.youtube.com/watch?v=ABkxMSbejZI
Once you understand the drawbacks, std::tie can help you (as shown).
Also, if all classes are public and simple, Boost.PFR https://www.boost.org/doc/libs/1_78_0/doc/html/boost_pfr.html
uj5u.com熱心網友回復:
struct iClass
{
int a;
char ch;
std::string msg;
// implement iClass == = operator
};
struct MyClass1 : virtual iClass{
// some virtual member functions
};
struct MyClass2 : virtual iClass {
// some virtual member functions
};
應該能夠與分配進行reintrepret_cast比較iClass。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/447266.html
