C ++ හි POD වර්ග මොනවාද?


996

මම මෙම යෙදුම POD- වර්ගය කිහිප වතාවක් දැක ඇත්තෙමි.
එයින් අදහස් කරන්නේ කුමක් ද?



5
කරුණාකර chat.stackoverflow.com/transcript/message/213026#213026 සහ පිළිගත් පිළිතුර ගැන සාකච්ඡා කිරීම සඳහා ඊළඟ දවසේ පණිවිඩ බලන්න
ජොහැන්නස් ෂෝබ් - litb


@ paxos1977: කරුණාකර ඔබේ “විසඳුම” තේරීම වෙනස් කරන්න (දැනට හෙව්ගිල්ගේ පිළිතුර) එවිට මූලික වශයෙන් වැරදි පිළිතුරක් මෙහි අවසන් වන ගූගල් කරුවන් නොමඟ නොයනු ඇත.
චියර්ස් සහ එච්. - ඇල්ෆ්

සී-ස්ටයිල් නූලක් POD වර්ගයක් නොවන බව අපි නිගමනය කර ඇත්තෙමු. 1.) දර්ශකය නූල් දත්ත සමඟ නොගැලපෙන අතර, 2.) නූලක් POD වර්ගයක් බවට පත් කිරීම සඳහා, ඔබ වර්ගය සහතික කළ යුතුය POD වර්ගයේ පූර්ව නිශ්චිත ප්‍රමාණය තුළ එහි නිල්-කාලීන වර්‍ගයක් තිබීම, නිර්වචනය නොකළ හැසිරීමට හේතු වේ.

Answers:


707

POD යනු සරල පැරණි දත්තයි - එනම්, ඉදිකිරීම්කරුවන්, විනාශ කරන්නන් සහ අථත්ය සාමාජිකයන් නොමැතිව පන්තියක් (යතුරුපදය structහෝ මූල පදය සමඟ අර්ථ දක්වා තිබේද class). POD පිළිබඳ විකිපීඩියා ලිපිය තව ටිකක් විස්තරාත්මකව ගොස් එය අර්ථ දක්වන්නේ:

සී ++ හි සරල පැරණි දත්ත ව්‍යුහයක් යනු සාමාජිකයින් ලෙස PODS පමණක් අඩංගු වන, පරිශීලක-නිර්වචනය කළ විනාශ කරන්නෙකු, පරිශීලක-නිර්වචනය කළ පිටපත් පැවරුම් ක්‍රියාකරුවෙකු නොමැති අතර, පොයින්ටර්-ට-සාමාජික වර්ගයේ අස්ථිර සාමාජිකයන් නොමැත.

C ++ 98/03 සඳහා මෙම පිළිතුරෙන් වැඩි විස්තර සොයාගත හැකිය . C ++ 11 විසින් POD අවට ඇති නීති වෙනස් කර ඇති අතර ඒවා බෙහෙවින් ලිහිල් කර ඇති අතර එමඟින් පසු විපරම් පිළිතුරක් අවශ්‍ය වේ.


35
වෙනසක් තියෙනවා. සහජ වර්ග වන්නේ “බිල්ඩින්” භාෂා ප්‍රාථමිකයන් ය. POD වර්ග මේවා වේ, තවද මේවායේ (සහ වෙනත් PODs) එකතුව.
ඇඩම් රයිට්

59
POD වර්ග වලට POD නොවන වර්ගවල ලක්ෂණ නොමැත. නිදසුනක් ලෙස, ඔබට ගෝලීය, සංයුක්ත, POD වර්ගයේ ව්‍යුහයක් තිබේ නම්, ඔබට එහි අන්තර්ගතය වරහන් අංකනයකින් ආරම්භ කළ හැකිය, එය කියවීමට පමණක් මතකය තුළට දමනු ලැබේ, එය ආරම්භ කිරීම සඳහා කේතයක් ජනනය කිරීම අවශ්‍ය නොවේ (ඉදිකිරීම්කරු හෝ වෙනත් ආකාරයකින්), එය වැඩසටහන් රූපයේ කොටසක් නිසා. බොහෝ විට RAM, ROM, හෝ Flash මත දැඩි සීමාවන් ඇති කාවැද්දූ පුද්ගලයින් සඳහා මෙය වැදගත් වේ.
මයික් ඩෙසිමොන්

35
C ++ 11 හි, ඔබට MyType POD ද යන්න පැවසීමට std :: is_pod <MyType> () කළ හැකිය.
allyourcode

7
C ++ කාර්ය සාධනය පිළිබඳ Bjarne Stroustrup හි තාක්ෂණික වාර්තාවෙහි දැක්වෙන්නේ C ++ ප්‍රමිතිය POD විස්තර කරන්නේ “ C හි පිරිසැලසුම, ආරම්භ කිරීම සහ memcpy සමඟ පිටපත් කිරීමේ හැකියාව වැනි සමාන දත්ත වර්ගයට අනුකූල වන දත්ත වර්ගයක් ” ලෙස ය. සමහර විට POD වර්ගයක් සහ POD ව්‍යුහයක් අතර වෙනසක් තිබිය යුතුය.
user34660

6
-1 මේ පිළිතුර තවමත් මූලිකව වැරදි සහ නොමඟ යවන 16 අගෝස්තු 2016 වන විට වේ: Pod වර්ග පන්ති වර්ග කිරීමට සීමා නො වේ.
චියර්ස් සහ එච්. - ඇල්ෆ්

358

ඉතා අවිධිමත් ලෙස:

POD යනු ව්‍යුහය තුළ "මැජික්" සිදු නොවන බවට C ++ සම්පාදකයා සහතික කරන වර්ගයකි (නිදසුනක් ලෙස): නිදසුනක් ලෙස vtables වෙත සැඟවුණු දර්ශක, වෙනත් වර්ග වලට දැමූ විට ලිපිනයට අදාළ වන ඕෆ්සෙට් ( අවම වශයෙන් ඉලක්කයේ POD ද නම්), ඉදිකිරීම්කරුවන් හෝ විනාශ කරන්නන්. දළ වශයෙන් කිවහොත්, වර්ගයක් යනු POD එකක් වන අතර එහි ඇති එකම දේ ගොඩනංවන ලද වර්ග සහ ඒවායේ සංයෝජන වේ. ප්‍රති result ලය වන්නේ සී වර්ගයක් ලෙස ක්‍රියා කරන දෙයකි.

අවිධිමත් ලෙස අඩු:

  • int, char, wchar_t, bool, float, doubleකරල් ආහාරයට ගැනීම, වේ පරිදි වේ long/shortහා signed/unsignedඔවුන් අනුවාද.
  • දර්ශකයන් (දර්ශකයේ සිට ක්‍රියාකාරීත්වය සහ දර්ශකයේ සිට සාමාජිකයා ඇතුළුව) PODs වේ,
  • enums PODs වේ
  • a constහෝ volatilePOD යනු POD ය.
  • a class, structහෝ unionPODs යනු සියලුම ස්ථිතික නොවන දත්ත සාමාජිකයින් වන POD එකක් publicවන අතර එයට මූලික පංතියක් නොමැති අතර ඉදිකිරීම්කරුවන්, විනාශ කරන්නන් හෝ අථත්‍ය ක්‍රම නොමැත. ස්ථිතික සාමාජිකයන් මෙම රීතිය යටතේ යමක් POD වීම නවත්වන්නේ නැත. මෙම නියමය C ++ 11 හි වෙනස් වී ඇති අතර සමහර පුද්ගලික සාමාජිකයින්ට අවසර ඇත: සියලුම පුද්ගලික සාමාජිකයන් සිටින පන්තියකට POD පන්තියක් විය හැකිද?
  • විකිපීඩියාව, POD ට වර්ගයේ දර්ශකයේ සිට සාමාජිකයෙකු සිටිය නොහැකි යැයි පැවසීම වැරදිය. නැතහොත්, සී ++ 98 වචන සඳහා එය නිවැරදිය, නමුත් ටීසී 1 පැහැදිලිවම කියා සිටියේ පොයින්ටර්ස් සිට සාමාජිකයා දක්වා POD බවයි.

විධිමත් ලෙස (C ++ 03 සම්මත):

3.9 (10): "අංක ගණිත වර්ග (3.9.1), ගණන් කිරීමේ වර්ග, දර්ශක වර්ග, සහ සාමාජික වර්ග සඳහා දර්ශකය (3.9.2) සහ මෙම වර්ගවල සීවී-සුදුසුකම් සහිත අනුවාදයන් (3.9.3) සාමූහිකව ඇමතුම් පරිමාණ වර්ග වේ. වර්ග, POD-struct වර්ග, POD- යූනියන් වර්ග (9 වන වගන්තිය), එවැනි වර්ගවල අරා සහ මෙම වර්ගවල cv- සුදුසුකම් සහිත අනුවාදයන් (3.9.3) සාමූහිකව POD වර්ග ලෙස හැඳින්වේ.

9 (4): “POD-struct යනු සමස්ත පන්තියක් වන අතර එය POD නොවන ව්‍යුහය, POD නොවන සංගමය (හෝ එවැනි වර්ගවල පෙළ) හෝ ස්ථිතික නොවන ස්ථිතික නොවන දත්ත සාමාජිකයන් නොමැති අතර පරිශීලකයෙකු නොමැත. පිටපත් ක්‍රියාකරු නිර්වචනය කරන්න සහ පරිශීලක-නිර්වචනය කළ විනාශ කරන්නෙකු නැත. ඒ හා සමානව POD- සංගමය යනු POD නොවන ව්‍යුහය, POD නොවන සංගමය (හෝ එවැනි වර්ගවල පෙළ) හෝ යොමු වල ස්ථිතික නොවන දත්ත සාමාජිකයන් නොමැති සමස්ත සංගමයකි. සහ පරිශීලක-නිර්වචනය කළ පිටපත් ක්‍රියාකරුවෙකු සහ පරිශීලක-නිර්වචනය කළ විනාශ කරන්නෙකු නොමැත.

8.5.1 (1): “සමස්ථයක් යනු පරිශීලක-ප්‍රකාශිත ඉදිකිරීම්කරුවන් නොමැති (12.1), පුද්ගලික හෝ ආරක්ෂිත ස්ථිතික නොවන දත්ත සාමාජිකයන් (11 වන වගන්තිය), මූලික පන්ති (10 වන වගන්තිය) නොමැති අරාව හෝ පන්තිය (9 වන වගන්තිය) ය. අතථ්‍ය කාර්යයන් නොමැත (10.3).


3
ඔබට විධිමත් / අඩු විධිමත් ඇත. ඔබට නියමය එකතු කළ හැකිය. වර්ගවල සහ වර්ගවල ගොඩනගා ඇති වර්ගවල (හෝ එවැනි දෙයක්). නිශ්චිත අර්ථ දැක්වීම ලබා ගැනීමට අමතරව දැනුම භාවිතා කිරීම පහසු කිරීම සඳහා අපට අවශ්‍ය වේ.
මාටින් යෝක්

1
" වෙනත් වර්ගයකට වාත්තු කරන විට ඕෆ්සෙට්" වල ඔබ ටිකක් වැරදියි . පාදක හෝ ව්‍යුත්පන්න පන්තියකට වාත්තු කිරීමේදී එම ඕෆ්සෙට් යොදනු ලැබේ. එබැවින්, ඔබ POD පාදක පන්තියේ දර්ශකයේ සිට POD නොවන ව්‍යුත්පන්න පන්තියකට දැමුවහොත්, ඔබට තවමත් ගැලපීමක් සිදුවිය හැකිය.
MSalters

1
Te ස්ටීව් ජෙසොප්: අපි POD සහ POD නොවන අය අතර වෙනස හඳුනාගත යුත්තේ ඇයි?
ලේසර්

6
Az ලේසර්: එය අනෙක් ප්‍රශ්නයකි, "PODs හැසිරෙන්නේ කෙසේද?" "POD යන්නෙන් අදහස් කරන්නේ කුමක්ද?" සාරාංශයක් ලෙස වෙනස ආරම්භයට සම්බන්ධ වේ (එම නිසා වස්තු අනුපිටපත් කිරීම සඳහා මෙම්ක්පී භාවිතා කිරීම), එම සම්පාදකයා සඳහා සී ව්‍යුහ සැකැස්ම සමඟ අනුකූල වීම සහ ඉහළට සහ පහළට වාත්තු කිරීම. PODs "C වර්ග මෙන් ක්‍රියා කරයි", POD නොවන අය එසේ කිරීමට සහතික නොවේ. එබැවින් ඔබේ වර්ගය සී ව්‍යුහයක් ලෙස ක්‍රියා කිරීමට ඔබට අවශ්‍ය නම්, එය POD බව සහතික කළ යුතුය, එබැවින් ඔබ වෙනස දැනගත යුතුය.
ස්ටීව් ජෙසොප්

4
untmuntoo: ඇත්ත වශයෙන්ම මම අදහස් දක්වමින් සිටියේ විකිපීඩියාවෙන් යල්පැනගිය තොරතුරු උපුටා දක්වන පිළිතුරයි. මට එම පිළිතුර සංස්කරණය කළ හැකි යැයි මම සිතමි, නමුත් මා කොතරම් නිවැරදි යැයි සිතුවත්, මගේ එකඟතාවයට වෙනත් අයගේ පිළිතුරු සංස්කරණය කිරීමට ගියහොත් මට කරදරයක් දැනේ.
ස්ටීව් ජෙසොප්

24

සරල පැරණි දත්ත

කෙටියෙන් කිවහොත්, එය සියලු බිල්ට් ඇත දත්ත වර්ග (උදා: int, char, float, long, unsigned char, double, ආදිය) හා Pod දත්ත සියල්ල ඒකරාශි. ඔව්, එය පුනරාවර්තන අර්ථ දැක්වීමකි. ;)

වඩාත් පැහැදිලිව කිවහොත්, POD යනු අප හඳුන්වන්නේ “struct”: දත්ත ගබඩා කරන ඒකකයක් හෝ ඒකක සමූහයකි.


13
අපි සමහර විට ඒවා 'ව්‍යුහයක්' ලෙස හඳුන්වන බව සත්‍යයකි. කෙසේ වෙතත්, අපි සෑම විටම එසේ කිරීම වැරදියි, මන්ද ව්‍යුහයක් අනිවාර්යයෙන්ම POD වර්ගයක් නොවන බැවිනි.
ස්ටීව් ජෙසොප්

7
පැහැදිලිවම ... ව්‍යුහය සහ පංතිය බොහෝ දුරට සමාන ය, නමුත් "ව්‍යාපාරය" තුළ අපි 'ව්‍යුහයක්' ලෙස හඳුන්වන්නේ සරල දත්ත එකතු කරන්නෙකු වන අතර සාමාන්‍යයෙන් ctors සහ dtor නොමැතිව සාමාන්‍යයෙන් වටිනාකම් අර්ථකථන සහිතව ...
ugasoft

2
මට නම් C ++ පන්තියේ මූල පදයට සමාන හෝ ඊට ආසන්නව සෑදීම වැරදිය: struct පමණක් පන්තියට පොදු පෙරනිමි ප්‍රවේශය එක් කරයි. සී-වැනි ව්‍යුහයන් සෑදීම සඳහා මම වඩාත් සරල වූ අතර, සී ++ හි 0 වන දින අපට PODs තිබෙන්නට ඇත.
user1708042

ugasoft: ඔබේ පිළිතුර නොමඟ යවන සුළු විය හැකිය - ඔබේ අදහස් දැක්වීමේදී එය සම්මතයට වඩා ප්‍රායෝගිකව භාවිතා වන බවට නැතිවූ විස්තරයක් පැහැදිලි කළේය. අවුරුදු 8 යි, ඔබත් මෙහි සිටිනවාද? ;-)
hauron

නූලක් හැරුණු විට ඔබට එය දිගින් දිගට තීරණය නොකර memcpy සමඟ පිටපත් කළ නොහැක.

13

POD සහ POD නොවන ඒවා අතර වෙනස හඳුනා ගැනීමට අපට අවශ්‍ය ඇයි?

සී ++ සිය ජීවිතය සී හි දිගුවක් ලෙස ආරම්භ කළ අතර නූතන සී ++ තවදුරටත් සී හි දැඩි සුපර්සෙට් එකක් නොවූවත්, මිනිසුන් තවමත් ඉහළ මට්ටමේ අනුකූලතාවයක් අපේක්ෂා කරයි.

දළ වශයෙන් කිවහොත්, POD වර්ගයක් යනු C සමඟ අනුකූල වන වර්ගයක් වන අතර සමහර විට ඒබීඅයි ප්‍රශස්තිකරණය සමඟ අනුකූල වේ.

සී සමඟ අනුකූල වීමට නම්, අප විසින් සීමාවන් දෙකක් සපුරාලිය යුතුය.

  1. පිරිසැලසුම අනුරූප සී වර්ගයට සමාන විය යුතුය.
  2. වර්ගය අනුරූපී සී වර්ගයට සමාන ආකාරයකින් ශ්‍රිත වෙත ආපසු ලබා දිය යුතුය.

සමහර C ++ විශේෂාංග මෙයට නොගැලපේ.

අථත්ය ක්රම සඳහා සම්පාදකයාට අථත්ය ක්රම වගු වෙත දර්ශක එකක් හෝ කිහිපයක් ඇතුළත් කිරීම අවශ්ය වේ, එය සී හි නොපවතී.

පරිශීලක-නිර්වචනය කරන ලද පිටපත් සාදන්නන්, චලනය වන ඉදිකිරීම්කරුවන්, පිටපත් පැවරුම් සහ විනාශ කරන්නන් පරාමිති සම්මත කිරීම සහ නැවත පැමිණීම සඳහා ඇඟවුම් කරයි. බොහෝ සී ඒබීඅයි ලේඛකයන් තුළ කුඩා පරාමිතීන් පසුකර ආපසු එවයි, නමුත් පරිශීලක අර්ථ දක්වා ඇති ඉදිකිරීම්කරු / පැවරුම් / ඩිස්ට්‍රැක්ටර් වෙත යොමු කරන ලද ක්‍රියා කළ හැක්කේ මතක ස්ථාන සමඟ පමණි.

එබැවින් "සී අනුකූල" යැයි අපේක්ෂා කළ හැකි වර්ග මොනවාද සහ නොකළ හැකි වර්ග මොනවාද යන්න නිර්වචනය කිරීමේ අවශ්‍යතාවයක් පවතී. C ++ 03 මේ සම්බන්ධයෙන් තරමක් දැඩි වූ අතර, ඕනෑම පරිශීලක-නිර්වචනය කළ ඉදිකිරීම්කරුවෙකු විසින් ගොඩනඟන ලද ඉදිකිරීම්කරුවන් අක්‍රීය කරනු ඇති අතර ඒවා නැවත එකතු කිරීමට ගන්නා ඕනෑම උත්සාහයක් හේතුවෙන් ඒවා පරිශීලක අර්ථ දැක්වීමක් වනු ඇත. C ++ 11 මඟින් දේවල් තරමක් දුරට විවර කරන ලදි, පරිශීලකයාට ගොඩනඟන ලද ඉදිකිරීම්කරුවන් නැවත හඳුන්වා දීමට ඉඩ දීමෙන්.


12

මා තේරුම් ගත් පරිදි POD (PlainOldData) යනු අමු දත්ත පමණි - එයට අවශ්‍ය නොවේ:

  • ඉදි කිරීමට,
  • විනාශ කිරීමට,
  • අභිරුචි ක්‍රියාකරුවන් ඇති කිරීමට.
  • අතථ්‍ය කාර්යයන් නොතිබිය යුතුය,
  • සහ ක්‍රියාකරුවන් අභිබවා නොයා යුතුය.

යමක් POD එකක් දැයි පරීක්ෂා කරන්නේ කෙසේද? හොඳයි, ඒ සඳහා ව්‍යුහයක් තිබේ std::is_pod:

namespace std {
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
  struct is_pod
  : public integral_constant<bool, __is_pod(_Tp)>
  { };
}

(ශීර්ෂයේ type_traits වෙතින්)


යොමුව:


2
වැරදියි, POD වර්ගයක සාමාජික කාර්යයන් හෝ අධික ලෙස පටවන ක්‍රියාකරුවන් තිබිය හැක. (නමුත් එයට අතථ්‍ය සාමාජික ක්‍රියාකාරකම් නොතිබිය හැකිය.)
කොලින් ඩී බෙනට්

@ කොලින් ඩී බෙනට් ඔව්, ඒක ඇත්ත. ව්යාකූලත්වයට කණගාටුයි. Anwser තුළට / පිටතට සංස්කරණය කර ඇත.
набиячлэвэли

11

POD (සරල පැරණි දත්ත) වස්තුවකට මෙම දත්ත වර්ග වලින් එකක් ඇත - මූලික වර්ගයක්, දර්ශකයක්, සංගමයක්, ව්‍යුහයක්, අරාවක් හෝ පන්තියක් - කිසිදු ඉදිකිරීම්කරුවෙකු නොමැතිව. අනෙක් අතට, POD නොවන වස්තුවක් යනු ඉදිකිරීම්කරුවෙකු සිටින එකකි. POD වස්තුවක් එහි වර්ගය සඳහා නිසි ප්‍රමාණයෙන් ගබඩාව ලබා ගන්නා විට එහි ආයු කාලය ආරම්භ කරන අතර වස්තුව සඳහා ආචයනය නැවත භාවිතා කරන විට හෝ අවලංගු කරන විට එහි ආයු කාලය අවසන් වේ.

PlainOldData වර්ගවල ද කිසිවක් නොතිබිය යුතුය:

  • අතථ්‍ය ශ්‍රිත (ඔවුන්ගේම හෝ උරුම වූ)
  • අතථ්‍ය පාදක පන්ති (සෘජු හෝ වක්‍ර).

ප්ලේන් ඕල්ඩ් ඩේටා හි ලිහිල් අර්ථ දැක්වීම සඳහා ඉදිකිරීම්කරුවන් සහිත වස්තු ඇතුළත් වේ; නමුත් අතථ්‍ය කිසිවක් ඇති අය බැහැර කරයි. ප්ලේන් ඕල්ඩ් ඩේටා වර්ග සමඟ ඇති වැදගත් ගැටළුව නම් ඒවා බහු අවයවික නොවන බවයි. උරුමය POD වර්ග සමඟ කළ හැකිය, කෙසේ වෙතත් එය කළ යුත්තේ ක්‍රියාත්මක කිරීමේ ඉන්හෙරිටන්ස් (කේත නැවත භාවිතා කිරීම) සඳහා මිස බහුමාපකය / උප වර්ගය නොවේ.

පොදු (තදින් නිවැරදි නොවේ) අර්ථ දැක්වීමක් නම්, ප්ලේන් ඕල්ඩ් ඩේටා වර්ගය යනු වීටේබල් නොමැති ඕනෑම දෙයක් බවයි.


ඔබගේ පිළිතුර ඉතා හොඳයි, නමුත් මෙම ප්‍රශ්නය මීට වසර 8 කට පෙර පිළිතුර පිළිගෙන ඇති අතර තවත් හොඳ පිළිතුරු කිහිපයක් තිබේ. තවම පිළිතුරු නොලැබූ ප්‍රශ්නවලට පිළිතුරු දීමට ඔබ දැනුම භාවිතා කරන්නේ නම් ඔබට SO වෙත වැඩි දායකත්වයක් ලබා දිය හැකිය)))
mvidelgauz

8

static_assertC ++ 11 සිට C ++ 17 සහ POD ආචරණයන් සහිත සියලුම POD නොවන අවස්ථා සඳහා උදාහරණ

std::is_pod C ++ 11 හි එකතු කරන ලදි, එබැවින් දැනට එම ප්‍රමිතිය සලකා බලමු.

std::is_podhttps://stackoverflow.com/a/48435532/895245 හි සඳහන් පරිදි C ++ 20 වෙතින් ඉවත් කරනු ලැබේ , ප්‍රතිස්ථාපනය සඳහා සහය ලැබෙන බැවින් මෙය යාවත්කාලීන කරමු.

ප්‍රමිතිය පරිණාමය වන විට POD සීමා කිරීම් වඩ වඩාත් ලිහිල් වී ඇත, උදාහරණයේ ඇති සියලුම ලිහිල් කිරීම් ifdefs හරහා ආවරණය කිරීම මගේ අරමුණයි.

++ libstdc දී පරීක්ෂා කිරීමේ කුඩා ටිකක් දී ඇත: https://github.com/gcc-mirror/gcc/blob/gcc-8_2_0-release/libstdc%2B%2B-v3/testsuite/20_util/is_pod/value.cc නමුත් එය ඉතා කුඩායි. නඩත්තු කරන්නන්: ඔබ මෙම ලිපිය කියවන්නේ නම් කරුණාකර මෙය ඒකාබද්ධ කරන්න. මෙහි සඳහන් සියලුම C ++ පරීක්ෂණ ව්‍යාපෘති පරීක්ෂා කිරීමට මට කම්මැලි ය: /software/199708/is-there-a-compliance-test-for-c-compilers

#include <type_traits>
#include <array>
#include <vector>

int main() {
#if __cplusplus >= 201103L
    // # Not POD
    //
    // Non-POD examples. Let's just walk all non-recursive non-POD branches of cppreference.
    {
        // Non-trivial implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/TrivialType
        {
            // Has one or more default constructors, all of which are either
            // trivial or deleted, and at least one of which is not deleted.
            {
                // Not trivial because we removed the default constructor
                // by using our own custom non-default constructor.
                {
                    struct C {
                        C(int) {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // No, this is not a default trivial constructor either:
                // https://en.cppreference.com/w/cpp/language/default_constructor
                //
                // The constructor is not user-provided (i.e., is implicitly-defined or
                // defaulted on its first declaration)
                {
                    struct C {
                        C() {}
                    };
                    static_assert(std::is_trivially_copyable<C>(), "");
                    static_assert(!std::is_trivial<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }
            }

            // Not trivial because not trivially copyable.
            {
                struct C {
                    C(C&) {}
                };
                static_assert(!std::is_trivially_copyable<C>(), "");
                static_assert(!std::is_trivial<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }
        }

        // Non-standard layout implies non-POD.
        // https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
        {
            // Non static members with different access control.
            {
                // i is public and j is private.
                {
                    struct C {
                        public:
                            int i;
                        private:
                            int j;
                    };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // These have the same access control.
                {
                    struct C {
                        private:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");

                    struct D {
                        public:
                            int i;
                            int j;
                    };
                    static_assert(std::is_standard_layout<D>(), "");
                    static_assert(std::is_pod<D>(), "");
                }
            }

            // Virtual function.
            {
                struct C {
                    virtual void f() = 0;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Non-static member that is reference.
            {
                struct C {
                    int &i;
                };
                static_assert(!std::is_standard_layout<C>(), "");
                static_assert(!std::is_pod<C>(), "");
            }

            // Neither:
            //
            // - has no base classes with non-static data members, or
            // - has no non-static data members in the most derived class
            //   and at most one base class with non-static data members
            {
                // Non POD because has two base classes with non-static data members.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {
                        int j;
                    };
                    struct C : Base1, Base2 {};
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // POD: has just one base class with non-static member.
                {
                    struct Base1 {
                        int i;
                    };
                    struct C : Base1 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }

                // Just one base class with non-static member: Base1, Base2 has none.
                {
                    struct Base1 {
                        int i;
                    };
                    struct Base2 {};
                    struct C : Base1, Base2 {};
                    static_assert(std::is_standard_layout<C>(), "");
                    static_assert(std::is_pod<C>(), "");
                }
            }

            // Base classes of the same type as the first non-static data member.
            // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
            {
                struct C {};
                struct D : C {
                    C c;
                };
                //static_assert(!std::is_standard_layout<C>(), "");
                //static_assert(!std::is_pod<C>(), "");
            };

            // C++14 standard layout new rules, yay!
            {
                // Has two (possibly indirect) base class subobjects of the same type.
                // Here C has two base classes which are indirectly "Base".
                //
                // TODO failing on GCC 8.1 -std=c++11, 14 and 17.
                // even though the example was copy pasted from cppreference.
                {
                    struct Q {};
                    struct S : Q { };
                    struct T : Q { };
                    struct U : S, T { };  // not a standard-layout class: two base class subobjects of type Q
                    //static_assert(!std::is_standard_layout<U>(), "");
                    //static_assert(!std::is_pod<U>(), "");
                }

                // Has all non-static data members and bit-fields declared in the same class
                // (either all in the derived or all in some base).
                {
                    struct Base { int i; };
                    struct Middle : Base {};
                    struct C : Middle { int j; };
                    static_assert(!std::is_standard_layout<C>(), "");
                    static_assert(!std::is_pod<C>(), "");
                }

                // None of the base class subobjects has the same type as
                // for non-union types, as the first non-static data member
                //
                // TODO: similar to the C++11 for which we could not make a proper example,
                // but with recursivity added.

                // TODO come up with an example that is POD in C++14 but not in C++11.
            }
        }
    }

    // # POD
    //
    // POD examples. Everything that does not fall neatly in the non-POD examples.
    {
        // Can't get more POD than this.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<int>(), "");
        }

        // Array of POD is POD.
        {
            struct C {};
            static_assert(std::is_pod<C>(), "");
            static_assert(std::is_pod<C[]>(), "");
        }

        // Private member: became POD in C++11
        // /programming/4762788/can-a-class-with-all-private-members-be-a-pod-class/4762944#4762944
        {
            struct C {
                private:
                    int i;
            };
#if __cplusplus >= 201103L
            static_assert(std::is_pod<C>(), "");
#else
            static_assert(!std::is_pod<C>(), "");
#endif
        }

        // Most standard library containers are not POD because they are not trivial,
        // which can be seen directly from their interface definition in the standard.
        // /programming/27165436/pod-implications-for-a-struct-which-holds-an-standard-library-container
        {
            static_assert(!std::is_pod<std::vector<int>>(), "");
            static_assert(!std::is_trivially_copyable<std::vector<int>>(), "");
            // Some might be though:
            // /programming/3674247/is-stdarrayt-s-guaranteed-to-be-pod-if-t-is-pod
            static_assert(std::is_pod<std::array<int, 1>>(), "");
        }
    }

    // # POD effects
    //
    // Now let's verify what effects does PODness have.
    //
    // Note that this is not easy to do automatically, since many of the
    // failures are undefined behaviour.
    //
    // A good initial list can be found at:
    // /programming/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
    {
        struct Pod {
            uint32_t i;
            uint64_t j;
        };
        static_assert(std::is_pod<Pod>(), "");

        struct NotPod {
            NotPod(uint32_t i, uint64_t j) : i(i), j(j) {}
            uint32_t i;
            uint64_t j;
        };
        static_assert(!std::is_pod<NotPod>(), "");

        // __attribute__((packed)) only works for POD, and is ignored for non-POD, and emits a warning
        // /programming/35152877/ignoring-packed-attribute-because-of-unpacked-non-pod-field/52986680#52986680
        {
            struct C {
                int i;
            };

            struct D : C {
                int j;
            };

            struct E {
                D d;
            } /*__attribute__((packed))*/;

            static_assert(std::is_pod<C>(), "");
            static_assert(!std::is_pod<D>(), "");
            static_assert(!std::is_pod<E>(), "");
        }
    }
#endif
}

GitHub ඉහළට .

සමඟ පරීක්ෂා කර ඇත්තේ:

for std in 11 14 17; do echo $std; g++-8 -Wall -Werror -Wextra -pedantic -std=c++$std pod.cpp; done

උබුන්ටු 18.04, ජීසීසී 8.2.0.



-7

C ++ සමඟ, සරල පැරණි දත්ත යනු int, char, වැනි දේ පමණක් භාවිතා කරන බව නොවේ. සරල පැරණි දත්ත සැබවින්ම ප්‍රායෝගිකව අදහස් කරන්නේ ඔබට එය මතකයේ එක් ස්ථානයක සිට තවත් ස්ථානයකට ව්‍යුහාත්මක මතක සටහනක් ගෙන යා හැකි අතර ඔබ බලාපොරොත්තු වන ආකාරයටම දේවල් ක්‍රියාත්මක වනු ඇත (එනම් පුපුරවා නොයන්න). ඔබේ පන්තියට හෝ ඔබේ පන්තියට අයත් ඕනෑම පන්තියක සාමාජිකයෙකු ලෙස දර්ශකයක් හෝ යොමු කිරීමක් හෝ අතථ්‍ය ශ්‍රිතයක් ඇති පන්තියක් තිබේ නම් මෙය කැඩී යයි. අත්යවශ්යයෙන්ම, දර්ශකයන් කොතැනක හෝ සම්බන්ධ විය යුතු නම්, එය සරල පැරණි දත්ත නොවේ.


6
POD ව්‍යුහයන් තුළ දර්ශකයන්ට අවසර ඇත. යොමුව නොවේ.
j_random_hacker

1
මගියා මෙහි අතුරුදහන්.
අයිස්බයිට්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.