рдХрд╛рдВрд╕реНрдЯреНрд░реЗрдХреНрд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рдПрдХ рдХрд╛рд╕реНрдЯ рд╕реНрдкреЗрд╕рд┐рдпрд░ рдирд╣реАрдВ рд╣реИ

рдмрд╕ рдЖрдкрдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛: constexpr рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдПрдХ рдкрд╣рд▓реВ рдореЗрдВ рд╕реА ++ 14 рд╕реА ++ 11 рдХреЗ рд╕рд╛рде рдкреАрдЫреЗ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

C ++ 11 рдореЗрдВ, рдпрджрд┐ рдЖрдк рдПрдХ constexpr рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ constexpr рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдЧрд╛:
 // C++11 struct NonNegative { int i; constexpr int const& get() /*const*/ { return i; } int& get() { return i; } }; 

get рдлрд╝рдВрдХреНрд╢рди рдХреА рдкрд╣рд▓реА рдШреЛрд╖рдгрд╛ const рдХреЛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреА, рднрд▓реЗ рд╣реА рд╣рдо рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рди рдХрд░реЗрдВред рдЗрд╕рд▓рд┐рдП, рдЗрди рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрддрд┐рднрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: const рдФрд░ рдиреЙрди- const рд╕рдВрд╕реНрдХрд░рдгред

C ++ 14 рдореЗрдВ, рдпрд╣ рдЕрдм рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛: рджреЛрдиреЛрдВ рдШреЛрд╖рдгрд╛рдПрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд░рд┐рдЯрд░реНрди рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди, рдиреЙрди- const рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВрдЧреА - рдЗрд╕рд╕реЗ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╣реЛ рдЬрд╛рдПрдЧреАред рдпрджрд┐ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА constexpr рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд constexpr рд▓рд┐рдП рдЙрдореНрдореАрдж рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЖрдкрдХрд╛ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдВ рдпрджрд┐ рдЖрдк C ++ 14 рдХрдВрдкрд╛рдЗрд▓рд░реЛрдВ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВред

рдирд┐рд╣рд┐рдд const рд╕рд╛рде рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ?


рдпрджрд┐ рдЖрдк рд╣рдорд╛рд░реЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ рддреЛ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдВрдЧреА:
 // C++11 constexpr int i = NonNegative{2}.get(); // ERROR 

(рдХреБрдЫ рдЕрд╕рд╛рдорд╛рдиреНрдп) рд╕реА ++ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЬрдм рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЧреИрд░- const рд╕рдВрд╕реНрдХрд░рдг рдПрдХ const рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдиреЙрди- constexpr рдореЗрдВрдмрд░ рдлрдВрдХреНрд╢рди get , constexpr рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ constexpr рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ constexpr рд╕реНрдЯреЗрдЬ рдкрд░ рдПрд░рд░ рдорд┐рд▓реЗрдЧрд╛ред рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ constexpr рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ constexpr рдХреЛ рдЬреЛрдбрд╝ рджреЗрдЧрд╛ ...

рдореИрдВрдиреЗ рдХрд╣рд╛ рдХрд┐ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рдирд┐рдпрдо рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдереЛрдбрд╝реЗ рд╡рд┐рдкрд░реАрдд рд╣реИрдВ рдХрд┐ рд╣рдо рдЕрд╕реНрдерд╛рдпреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЧреИрд░-рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдЪреБрдирддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдиреЙрди- const рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдХреЗ рдХреЙрдиреНрд╕реНрдЯрд▓ рд▓реИрд╡рд▓реНрдпреВ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрддреЗ рд╣реИрдВ:
 // C++11 constexpr int const& get(NonNegative const& n) { return ni; } constexpr int& get(NonNegative& n) { return ni; } NonNegative N = readValue(); constexpr int * P = &get(N); int main() { *P = 1; } 

рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ: рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ N рдПрдХ рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╕реВрдЪрдХ P рдкреНрд░рд╛рд░рдВрдн рдкрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рджреВрд╕рд░рд╛, рдЧреИрд░- const рдЕрддрд┐рднрд╛рд░рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ P рд▓реЗрдХрд┐рди рдиреЙрди- constexpr рдлрдВрдХреНрд╢рди рдореЗрдВ рдЕрднреА рднреА constexpr ! рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐ рдирд┐рдпрдо " constexpr рдорддрд▓рдм рд╣реИ constexpr " рдХреЗрд╡рд▓ рдПрдХ рдЧреИрд░-рд╕реНрдереИрддрд┐рдХ рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЗ this рддрд░реНрдХ рдХреЛ рдирд┐рд╣рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред constexpr рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЧреИрд░- constexpr рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЧреИрд░- constexpr рд▓рд┐рдВрдХ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ: рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд╕реНрддреБ рдХрд╛ рдкрддрд╛ рд╕реНрдерд┐рд░ рд╣реИ рдФрд░ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрддрд╛ P рдкрд░ рдорд╛рди рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реИ рдФрд░ рдмрд╛рдж рдореЗрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрджрд┐ рдкрд┐рдЫрд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдХреБрдЫ рджреВрд░ рддрдХ рджрд┐рдЦрддрд╛ рд╣реИ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЕрдзрд┐рдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдЙрджрд╛рд╣рд░рдг:
 // C++11 constexpr NonNegative* address(NonNegative& n) { return &n; } NonNegative n{0}; // non-const constexpr NonNegative* p = address(n); 

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рд╕рджрд╕реНрдп рдХреЛ address рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛:
 // C++11 struct NonNegative { // ... constexpr NonNegative* maddress() { return this; } // ERROR }; NonNegative n{0}; // non-const constexpr NonNegative* p = n.maddress(); 

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ maddress рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ maddress рд╕рд╛рде рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, this NonNegative const* рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ рдЗрд╕реЗ NonNegative* рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдпрд╣ рд╕рджрд╕реНрдп рдлрд╝рдВрдХреНрд╢рди рд╕реНрд╡рдпрдВ const , рд▓реЗрдХрд┐рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд ( this ) рддрд░реНрдХ рд╣реИред рдПрдХ рд╕рджрд╕реНрдп рд╕рдорд╛рд░реЛрд╣ рдШреЛрд╖рдгрд╛ рдХреЛ рдЫрджреНрдо рдХреЛрдб рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
 // PSEUDO CODE struct NonNegative { // ... constexpr NonNegative* maddress(NonNegative const& (*this)); }; 

рдФрд░ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ, рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ рдХреЗ рд╡рд┐рдкрд░реАрдд, (рдХрднреА-рдХрднреА рдЕрд╡рд╛рдВрдЫрдиреАрдп) const рдХреНрд╡рд╛рд▓рд┐рдлрд╛рдпрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рдЕрд╕рдордорд┐рддрддрд╛ C ++ 14 рдореЗрдВ рд╣рдЯрд╛ рджреА рдЬрд╛рдПрдЧреАред рдпрджрд┐ рдЖрдк рдирд┐рд╣рд┐рдд рддрд░реНрдХ ( this ) рдХреЗ рд▓рд┐рдП const рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб C ++ 14 рдореЗрдВ рдорд╛рдиреНрдп рд╣реЛрдЧрд╛:
 // C++14 struct NonNegative { int i; constexpr int const& get() const { return i; } constexpr int& get() { return i; } }; 

Source: https://habr.com/ru/post/In184250/


All Articles