[問題] 如何強迫struct使用者另外額外賦值?

作者: mmmmei (mmm煤)   2024-04-09 05:19:05
完整標題:如何強迫struct使用者在使用copy assignment時,另外對其他某值另外賦值?
開發平台(Platform): (Ex: Win10, Linux, ...)
Mac
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
clang 14
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
X
問題(Question):
想請問各位C/CXX先進,我有個需求就是我有一個MyUniquePtr 繼承自unique_ptr,還會有
其他一般的struct包含了這個MyUniquePtr。那我在過程中我會有copy assignment的行為,
我只想要他copy那些一般的Plain Old Data,那個MyUniquePtr務必要求用的人另外對MyUni
quePtr賦值。
想請問我有無辦法用一些clang語法,包含preprocessing,在compile階段就發現使用者是
否有另外對MyUniquePtr賦值?我有一些想法但不知道是否可行
給MyUniquePtr的copy assignment overload中,標記為deprecated
1. 假如使用者有MyUniquePtr賦值,那他可標記一些東西,例如#define,或是某些flag?
這樣可以繞過這個deprecated(或搭配-Werror=deprecated-declarations?)
2. 假如使用者有額外賦值,他就可以用#pragma clang diagnostic ignored "-Wdeprecate
d-declarations"把他那賦值的包起來來silence error,但這deprecated是在別的header,
包在這邊看起來沒什麼用
想請問各位有什麼其他方法可以做到嗎,簡單說就是如果使用者沒有另外賦值,編譯就報錯
。如果有另外賦值,那就沒事。謝謝指教
餵入的資料(Input):
MyStruct s1;
MyStruct s2;
1. s1 = s2;
2. s1 = s2; s1.p_char = new char(100);
預期的正確結果(Expected Output):
1. 編譯失敗
2. 可編譯成功
錯誤結果(Wrong Output):
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
https://godbolt.org/z/3M5KveYWa
圖片供手機使用者方便閱讀
https://imgur.com/bXyms0J
補充說明(Supplement):
只能用到c++11
作者: firejox (Tangent)   2024-04-09 07:37:00
這樣設計的意義是什麼要這樣做就用setXX()來取代copy assignment 就好了copy assignment 直接delete
作者: lycantrope (阿寬)   2024-04-09 13:27:00
只能copy不能move 那為何要unique_ptr
作者: firejox (Tangent)   2024-04-09 15:12:00
operator的語意要越明確越好,不要有做一半的copy就copy,move就move。做一半只是變得更難維護而已
作者: chchwy (mat)   2024-04-09 19:16:00
unique_ptr 不允許 copy,因為不能有多個擁有者所以你在一個允許copy的struct裡面放unique_ptr本身就非常違和
作者: sarafciel (Cattuz)   2024-04-10 00:07:00
你的設計讓人困惑的點在於,所有的東西你都只要半套而已,你想要pod style,但你塞unique_ptr的那一刻他就不是pod了,你用unique_ptr卻不打算按move跟ownership的規則來玩,你想要做copy assignment,但你在做的事也只有一部分的copy,剩下來那一部分要不要copy要使用者自己去弄,老實說,這應該沒有比較直覺XD
作者: wulouise (在線上!=在電腦前)   2024-04-10 02:02:00
為什麼要user給值?你不能直接deep copy就好?是說如果要能copy為什麼不乾脆不要用unique_ptr直接用aggregatetype比如強迫該type一定要trivial copyable我覺得繼承unique_ptr這個設計也有點怪,你想要可以copy的uniq_ptr用意到底是什麼...refactor舊code?
作者: Dracarys (MayShowGunMore)   2024-04-10 09:44:00
優雅的方式:Reflection?http://wg21.link/p2996怕之後少加field的話,可以看一下X macro pattern
作者: wulouise (在線上!=在電腦前)   2024-04-10 09:59:00
規定所有人把放在trivially copyable的東西統統放MyStruct::mPod裡面,複製的時候只複製mPod很遺憾你不能阻止人亂塞但code review可以定他
作者: sarafciel (Cattuz)   2024-04-10 23:34:00
像樓上講的一樣,你可以把pod的部分包一個struct然後這裡可以考慮用繼承做:https://godbolt.org/z/YvszWx644
作者: wulouise (在線上!=在電腦前)   2024-04-11 22:08:00
樓上的做法不錯,不過我習慣aggregate
作者: pnpncat (meow)   2024-06-07 14:22:00
你就把 operator=(const MyStruct&) 直接 delete 掉然後做一個 operator=(const MyStruct::Src&) 來用再定義一個 MyStruct::Src operator(特殊要求) 來用這樣 s1 = s2 會編譯錯誤 s1 = s2(new char(100)) 會過這類作法可以實現你的要求 但我想你還是該想想這樣的設計是否真的好用 以及是否有其必要

Links booklink

Contact Us: admin [ a t ] ucptt.com