ู
ุฑุญุจุง ู
ุฑุฉ ุงุฎุฑู ุฅููุง ูุดุงุฑูู ู
ูุงูุฉ ู
ุซูุฑุฉ ููุงูุชู
ุงู
ุ ุชู
ุฅุนุฏุงุฏ ุชุฑุฌู
ุฉ ููุง ุฎุตูุตูุง ูุทูุงุจ ุงูุฏูุฑุฉ ุงูุชุฏุฑูุจูุฉ "C ++ Developer" .
ุงูููู
ูุฏููุง ู
ูุดูุฑ ุถูู ู
ู ูุจู MADdรกm Balรกzs. ุขุฏู
ูู ู
ููุฏุณ ุจุฑู
ุฌูุงุช ูู Verizon Smart Communities Hungary ููุทูุฑ ุชุญูููุงุช ุงูููุฏูู ููุฃูุธู
ุฉ ุงูู
ุฏู
ุฌุฉ. ุฃุญุฏ ุดุบูู ูู ุชุญุณูู ููุช ุงูุชุฌู
ูุน ุ ูุฐูู ูุงูู ุนูู ุงูููุฑ ุนูู ูุชุงุจุฉ ู
ูุดูุฑ ุถูู ุญูู ูุฐุง ุงูู
ูุถูุน. ูู
ููู ุฃู ุชุฌุฏ ุขุฏู
ุนูู ุงูุฅูุชุฑูุช ุนูู
LinkedIn .
ูู
ุณูุณูุฉ ู
ู ุงูู
ูุงูุงุช ุญูู ููููุฉ ุฌุนู SFINAE ุฃูููุฉ ุ ุดุงูุฏูุง ููููุฉ ุฌุนู ูุงูุจ SFINAE ุฎุงุต ุจูุง ู
ูุฌุฒุง ูู
ุนุจุฑุง.
ู
ุฌุฑุฏ ุฅููุงุก ูุธุฑุฉ ุนูู ุดููู ุงูุฃุตูู:
template<typename T> class MyClass { public: void MyClass(T const& x){} template<typename T_ = T> void f(T&& x, typename std::enable_if<!std::is_reference<T_>::value, std::nullptr_t>::type = nullptr){} };
ูู
ูุงุฑูุชูุง ู
ุน ูุฐุง ุงูุดูู ุงูุฃูุซุฑ ุชุนุจูุฑุง:
template<typename T> using IsNotReference = std::enable_if_t<!std::is_reference_v<T>>; template<typename T> class MyClass { public: void f(T const& x){} template<typename T_ = T, typename = IsNotReference <T_>> void f(T&& x){} };
ูู
ูููุง ุฃู ูุนุชูุฏ ุจุดูู ู
ุนููู ุฃูู ู
ู ุงูู
ู
ูู ุจุงููุนู ุงูุงุณุชุฑุฎุงุก ูุงูุจุฏุก ูู ุงุณุชุฎุฏุงู
ู ูู ุงูุฅูุชุงุฌ. ูู
ูููุง ุฐูู ุ ุฅูู ูุนู
ู ูู ู
ุนุธู
ุงูุญุงูุงุช ุ ููู - ูู
ุง ูุชุญุฏุซ ุนู ุงููุงุฌูุงุช - ูุฌุจ ุฃู ูููู ููุฏูุง ุขู
ููุง ูู
ูุซูููุง ุจู. ูู ูุฐุง ุตุญูุญุ ุฏุนููุง ูุญุงูู ุงุฎุชุฑุงูู!
ุงูุนูุจ ุฑูู
1: ูู
ูู ุชุฌุงูุฒ SFINAE
ุนุงุฏุฉ ุ ูุชู
ุงุณุชุฎุฏุงู
SFINAE ูุชุนุทูู ุฌุฒุก ู
ู ุงูููุฏ ุญุณุจ ุงูุญุงูุฉ. ูู
ูู ุฃู ูููู ูุฐุง ู
ููุฏูุง ููุบุงูุฉ ุฅุฐุง ุงุญุชุฌูุง ุฅูู ุชูููุฐ ุ ุนูู ุณุจูู ุงูู
ุซุงู ุ ูุธููุฉ abs ุงูู
ุนุฑูุฉ ู
ู ูุจู ุงูู
ุณุชุฎุฏู
ูุณุจุจ ู
ุง (ูุฆุฉ ุงูุญุณุงุจ ุงูู
ุนุฑูุฉ ู
ู ูุจู ุงูู
ุณุชุฎุฏู
ุ ูุงูุชุญุณูู ูู
ุนุฏุงุช ู
ุนููุฉ ุ ูุฃุบุฑุงุถ ุงูุชุฏุฑูุจ ุ ูู
ุง ุฅูู ุฐูู):
template< typename T > T myAbs( T val ) { return( ( val <= -1 ) ? -val : val ); } int main() { int a{ std::numeric_limits< int >::max() }; std::cout << "a: " << a << " myAbs( a ): " << myAbs( a ) << std::endl; }
ูุนุฑุถ ูุฐุง ุงูุจุฑูุงู
ุฌ ู
ุง ููู ุ ูุงูุฐู ูุจุฏู ุทุจูุนูุงู ุชู
ุงู
ูุง:
a: 2147483647 myAbs( a ): 2147483647
ูููู ูู
ูููุง ุงุณุชุฏุนุงุก ุฏุงูุฉ
abs
ุจูุง ุจุงุณุชุฎุฏุงู
ุงููุณุงุฆุท ุบูุฑ ุงูู
ููุนุฉ
T
ุ ูุณูููู ุงูุชุฃุซูุฑ ูุงุฑุซููุง:
nt main() { unsigned int a{ std::numeric_limits< unsigned int >::max() }; std::cout << "a: " << a << " myAbs( a ): " << myAbs( a ) << std::endl; }
ูู ุงููุงูุน ุ ูุนุฑุถ ุงูุจุฑูุงู
ุฌ ุงูุขู:
a: 4294967295 myAbs( a ): 1
ูู
ูุชู
ุชุตู
ูู
ูุธููุชูุง ููุนู
ู ู
ุน ุงููุณุงุฆุท ุบูุฑ ุงูู
ููุนุฉ ุ ูุฐูู ูุฌุจ ุนูููุง ุชูููุฏ ุงูู
ุฌู
ูุนุฉ ุงูู
ุญุชู
ูุฉ ู
ู
T
ู
ุน SFINAE:
template< typename T > using IsSigned = std::enable_if_t< std::is_signed_v< T > >; template< typename T, typename = IsSigned< T > > T myAbs( T val ) { return( ( val <= -1 ) ? -val : val ); }
ูุนู
ู ุงูุฑู
ุฒ ูู
ุง ูู ู
ุชููุน: ูุคุฏู ุงุณุชุฏุนุงุก myAbs ุจููุน ุบูุฑ ู
ูููุน ุฅูู ุญุฏูุซ ุฎุทุฃ ููุช ุงูุชุฑุฌู
ุฉ:
candidate template ignored: requirement 'std::is_signed_v<
unsigned int>' was not satisfied [with T = unsigned int]
ุงููุฑุตูุฉ SFINAE ุงูุฏููุฉ
ุซู
ู
ุง ูู ุงูุฎุทุฃ ูู ูุฐู ุงููุธููุฉุ ููุฅุฌุงุจุฉ ุนูู ูุฐุง ุงูุณุคุงู ุ ูุญุชุงุฌ ุฅูู ุงูุชุญูู ู
ู ููููุฉ ููุงู
myAbs ุจุชูููุฐ SFINAE.
template< typename T, typename = IsSigned<T> > T myAbs( T val );
myAbs
ูู ูุงูุจ ูุธููุฉ ู
ุน ููุนูู ู
ู ู
ุนูู
ุงุช ูุงูุจ ุงูุฅุฏุฎุงู. ุงูุฃูู ูู ุงูููุน ุงููุนูู ูููุณูุทุฉ ุงูุฏุงูุฉ ุ ูุงูุซุงูู ูู
IsSigned <
T >
ุงูุงูุชุฑุงุถู (ูุฅูุง
std::enable_if_t <
std::is_signed_v <
T >
>
ุฃู
std::enable_if <
std::is_signed_v <
T>, void>::type
ุ ููู ุจุฏูู
void
ุฃู ูุงุดู).
ููู ูู
ูู ุฃู ูุณู
ู
myAbs
ุ ููุงู 3 ุทุฑู:
int a{ myAbs( -5 ) }; int b{ myAbs< int >( -5 ) }; int c{ myAbs< int, void >( -5 ) };
ุงูู
ูุงูู
ุงุช ุงูุฃููู ูุงูุซุงููุฉ ูุงุถุญุฉ ูู
ุจุงุดุฑุฉ ุ ูููู ุงูุซุงูุซุฉ ู
ุซูุฑุฉ ููุงูุชู
ุงู
: ู
ุง ูู ุญุฌุฉ ุงููุงูุจ
void
ุ
ู
ุนูู
ุฉ ุงููุงูุจ ุงูุซุงูู ูู ู
ุฌูููุฉ ุ ูููุง ููุน ุงูุชุฑุงุถู ุ ููููุง ูุง ุชุฒุงู ู
ุนูู
ุฉ ูุงูุจ ุ ูุฐูู ูู
ููู ุชุญุฏูุฏูุง ุจุดูู ุตุฑูุญ. ูู ูุฐู ู
ุดููุฉุ ูู ูุฐู ุงูุญุงูุฉ ุ ูุฐู ู
ุดููุฉ ูุจูุฑุฉ ุญููุง. ูู
ูููุง ุงุณุชุฎุฏุงู
ุงููู
ูุฐุฌ ุงูุซุงูุซ ููุชุฌูู ูู ุณููููุง
unsigned int d{ myAbs< unsigned int, void >( 5u ) }; unsigned int e{ myAbs< unsigned int, void >( std::numeric_limits< unsigned int >::max() ) };
ูุฌู
ุน ูุฐุง ุงูุฑู
ุฒ ุจุดูู ุฌูุฏ ุ ููููู ูุคุฏู ุฅูู ูุชุงุฆุฌ ูุงุฑุซูุฉ ุ ูุชุฌูุจ ู
ุง ุงุณุชุฎุฏู
ูุงู SFINAE:
a: 4294967295 myAbs( a ): 1
ุณูุญู ูุฐู ุงูู
ุดููุฉ - ููู ุฃููุงู: ูู ููุงู ุฃู ุนููุจ ุฃุฎุฑูุ ุญุณูุง ...
ุงูุนูุจ ุฑูู
2: ูุง ูู
ูููุง ุชูููุฐ ุชุทุจููุงุช ู
ุญุฏุฏุฉ
ุงูุงุณุชุฎุฏุงู
ุงูุดุงุฆุน ุงูุขุฎุฑ ูู SFINAE ูู ุชูููุฑ ุชุทุจููุงุช ู
ุญุฏุฏุฉ ูุธุฑูู ููุช ุงูุชุฑุฌู
ุฉ ุงูู
ุญุฏุฏุฉ. ู
ุงุฐุง ูู ููุง ูุง ูุฑูุฏ ุญุธุฑ ุฏุนูุฉ
myAbs
ุจููู
myAbs
ูุชูุฏูู
ุชุทุจูู ุชุงูู ููุฐู ุงูุญุงูุงุชุ ูู
ูููุง ุงุณุชุฎุฏุงู
if constexpr ูู C ++ 17 (ุณููุงูุด ูุฐุง ูุงุญููุง) ุ ุฃู ูู
ูููุง:
template< typename T > using IsSigned = std::enable_if_t< std::is_signed_v< T > >; template< typename T > using IsUnsigned = std::enable_if_t< std::is_unsigned_v< T > >; template< typename T, typename = IsSigned< T > > T myAbs( T val ) { return( ( val <= -1 ) ? -val : val ); } template< typename T, typename = IsUnsigned< T > > T myAbs( T val ) { return val; }
ููู ู
ุง ูุฐุงุ
error: template parameter redefines default argument template< typename T, typename = IsUnsigned< T > > note: previous default template argument defined here template< typename T, typename = IsSigned< T > >
ุฃูู ุ ููุต ู
ุนูุงุฑ C ++ (C ++ 17 ุ ยง 17.1.16) ุนูู ู
ุง ููู :"ูุง ููุจุบู ุชูุฏูู
ุงููุณุงุฆุท ุงูุงูุชุฑุงุถูุฉ ูู
ุนูู
ุฉ ุงููุงูุจ ุจูุงุณุทุฉ ุฅุนูุงููู ู
ุฎุชูููู ูู ููุณ ุงููุทุงู."
ุนูููุง ุ ูุฐุง ุจุงูุถุจุท ู
ุง ูุนููุงู ...
ูู
ุงุฐุง ูุง ุชุณุชุฎุฏู
ุงูุนุงุฏูุฉ ุฅุฐุงุ
ูู
ูู ุฃู ูุณุชุฎุฏู
ูุง ููุท ูู ููุช ุงูุชุดุบูู:
template< typename T > T myAbs( T val ) { if( std::is_signed_v< T > ) { return ( ( val <= -1 ) ? -val : val ); } else { return val; } }
ุณูููู
ุงูู
ุญูู ุงูุจุฑู
ุฌู ุจุชุญุณูู ุงูุดุฑุท ูุฃูู
if (std::is_signed_v <
T>)
if (true)
ุฃู
if (false)
ุจุนุฏ ุฅูุดุงุก ุงููุงูุจ. ูุนู
ุ ู
ุน ุชุทุจูููุง ุงูุญุงูู ู
myAbs
ูุฐุง ุณูู ููุฌุญ. ููู ุจุดูู ุนุงู
ุ ููุฑุถ ูุฐุง ูููุฏูุง ูุงุฆูุฉ: ูุฌุจ ุฃู ุชููู
else
if
ู
else
ุตุงูุญุฉ ููู
T
ู
ุงุฐุง ูู ูู
ูุง ุจุชุบููุฑ ุชุทุจูููุง ููููุงู:
template< typename T > T myAbs( T val ) { if( std::is_signed_v< T > ) { return std::abs( val ); } else { return val; } } int main() { unsigned int a{ myAbs( 5u ) }; }
ุณูู ูุชุนุทู ููุฏูุง ุนูู ุงูููุฑ:
error: call of overloaded 'abs(unsigned int&)' is ambiguous
ูุฐุง ุงูุชูููุฏ ูู ู
ุง ูุญุฐูู SFINAE: ูู
ูููุง ูุชุงุจุฉ ุฑู
ุฒ ุตุงูุญ ููุท ูู
ุฌู
ูุนุฉ ูุฑุนูุฉ ู
ู T (ูู myAbs ุ ูููู ุตุงูุญูุง ููุฃููุงุน ุบูุฑ ุงูู
ููุนุฉ ููุท ุฃู ุตุงูุญูุง ููุฃููุงุน ุงูู
ููุนุฉ ููุท).
ุงูุญู: ูู
ูุฐุฌ ุขุฎุฑ ูู SFINAE
ู
ุงุฐุง ูู
ูููุง ุฃู ููุนู ููุชุบูุจ ุนูู ูุฐู ุงูุนููุจุ ุจุงููุณุจุฉ ููู
ุดููุฉ ุงูุฃููู ุ ูุฌุจ ุนูููุง ูุฑุถ ุงุฎุชุจุงุฑ SFINAE ุงูุฎุงุต ุจูุง ุจุบุถ ุงููุธุฑ ุนู ููููุฉ ุงุณุชุฏุนุงุก ุงูู
ุณุชุฎุฏู
ูู ููุธุงุฆููุง. ุญุงูููุง ุ ูู
ูู ุงูุชุญุงูู ุนูู ุงุฎุชุจุงุฑูุง ุนูุฏู
ุง ูุง ูุญุชุงุฌ ุงูู
ุชุฑุฌู
ุฅูู ุงูููุน ุงูุงูุชุฑุงุถู ูู
ุนูู
ุฉ ุงููุงูุจ ุงูุซุงูู.
ู
ุงุฐุง ูู ุงุณุชุฎุฏู
ูุง ููุฏ SFINAE ููุฅุนูุงู ุนู ููุน ู
ุนูู
ุฉ ูุงูุจ ุจุฏูุงู ู
ู ุชูุฏูู
ููุน ุงูุชุฑุงุถูุ ููุฌุฑุจ:
template< typename T > using IsSigned = std::enable_if_t< std::is_signed_v< T >, bool >; template< typename T, IsSigned< T > = true > T myAbs( T val ) { return( ( val <= -1 ) ? -val : val ); } int main() {
ูุญุชุงุฌ ุฅูู ุฃู ูููู IsSigned ููุนูุง ุขุฎุฑ ุบูุฑ ุงููุฑุงุบ ูู ุงูุญุงูุงุช ุงูุตุญูุญุฉ ุ ูุฃููุง ูุฑูุฏ ุชูุฏูู
ููู
ุฉ ุงูุชุฑุงุถูุฉ ููุฐุง ุงูููุน. ูุง ุชูุฌุฏ ููู
ุฉ ููููุน ุงููุงุฑุบ ุ ูุฐูู ูุฌุจ ุนูููุง ุงุณุชุฎุฏุงู
ุดูุก ุขุฎุฑ: bool ุ int ุ enum ุ nullptr_t ุ ุฅูุฎ. ุนุงุฏุฉู ู
ุง ุฃุณุชุฎุฏู
bool - ูู ูุฐู ุงูุญุงูุฉ ุ ุชุจุฏู ุงูุชุนุจูุฑุงุช ุฐุงุช ู
ุนูู:
template< typename T, IsSigned< T > = true >
ุฅูู ูุนู
ู! ุจุงููุณุจุฉ ุฅูู
myAbs (5u)
ูููู ุงูู
ุชุฑุฌู
ุฎุทุฃ ุ ูู
ุง ูุงู ู
ู ูุจู:
candidate template ignored: requirement 'std::is_signed_v<unsigned int>' was not satisfied [with T = unsigned int
ุงูู
ูุงูู
ุฉ ุงูุซุงููุฉ ุ
myAbs <
int> (5u)
ูุง ุชุฒุงู ุตุงูุญุฉ ุ ููุญู ูููู ูููุน ุงูู
ุญูู ุงูุจุฑู
ุฌู
T
ุตุฑุงุญุฉ ุ ูุฐูู ูุญูู
5u
ุฅูู
int
.
ุฃุฎูุฑูุง ุ ูู
ูุนุฏ ุจุฅู
ูุงููุง ุชุชุจุน
myAbs
ุญูู ุงูุฅุตุจุน:
myAbs <
unsigned int, true> (5u)
ูููู ุฎุทุฃ. ูุง ููู
ุฅุฐุง ูุฏู
ูุง โโููู
ุฉ ุงูุชุฑุงุถูุฉ ูู ุงูู
ูุงูู
ุฉ ุฃู
ูุง ุ ูุชู
ุชูููู
ุฌุฒุก ู
ู ุชุนุจูุฑ SFINAE ุนูู ุฃู ุญุงู ุ ูุฃู ุงูู
ุชุฑุฌู
ูุญุชุงุฌ ุฅูู ููุน ูุณูุทุฉ ู
ู ููู
ุฉ ูุงูุจ ู
ุฌูููุฉ.
ูู
ูููุง ุงูุงูุชูุงู ุฅูู ุงูู
ุดููุฉ ุงูุชุงููุฉ - ููู ุงูุชุธุฑ ูุญุธุฉ! ุฃุนุชูุฏ ุฃููุง ูู
ูุนุฏ ูุชุฌุงูุฒ ุงููุณูุทุฉ ุงูุงูุชุฑุงุถูุฉ ูู
ุนูู
ุฉ ุงููุงูุจ ููุณูุง ุ ูู
ุง ูู ุงูู
ููู ุงูุฃุตููุ
template< typename T, typename = IsUnsigned< T > > T myAbs( T val ); template< typename T, typename = IsSigned< T > > T myAbs( T val );
ูููู ุงูุขู ู
ุน ุงูููุฏ ุงูุญุงูู:
template< typename T, IsUnsigned< T > = true > T myAbs( T val ); template< typename T, IsSigned< T > = true > T myAbs( T val );
ูุจุฏู ู
ุดุงุจูุงู ููุบุงูุฉ ููุฑู
ุฒ ุงูุณุงุจู ุ ูุฐูู ูุฏ ูุนุชูุฏ ุฃู ูุฐุง ูู ููุฌุญ ุฃูุถูุง ุ ูููู ูู ุงูุญูููุฉ ูุฐุง ุงูุฑู
ุฒ ูุง ููุงุฌู ููุณ ุงูู
ุดููุฉ. ู
ุง ูู
IsUnsigned <
T>
ุ ู
ูุทูู ุฃู ูุดู ุงูุจุญุซ. ูู
ุง ูู
IsSigned <
T>
ุ ููุณ ุงูุดูุก ุ ูููู ุฅุฐุง ูุงู ุฃุญุฏูู
Bool ุ ูุฅู ุงูุขุฎุฑ ูู ุนู
ููุฉ ุจุญุซ ูุงุดูุฉ.
ูุฐุง ูุนูู ุฃููุง ูุง ูุชุฌุงูุฒ ุงููุณูุทุงุช ุงูุงูุชุฑุงุถูุฉ ุ ูุธุฑูุง ููุฌูุฏ ุฏุงูุฉ ูุงุญุฏุฉ ููุท ู
ุน bool ูุณูุทุฉ ุงููุงูุจ ุ ูุงูุขุฎุฑ ุจุฏูู ูุงุดู ุ ูุฐูู ูุง ูุฌูุฏ ูู.
ุงูุณูุฑ ุงููุญูู
UPD. ุชู
ุญุฐู ูุฐู ุงูููุฑุฉ ู
ู ูุจู ุงูู
ุคูู ุจุณุจุจ ูุฌูุฏ ุฃุฎุทุงุก ูููุง.ุงูุฅุตุฏุงุฑุงุช ุงููุฏูู
ุฉ ู
ู C ++
ูู ู
ุง ุณุจู ูุนู
ู ู
ุน ุงูุฅุตุฏุงุฑ C ++ 11 ุ ูุงููุฑู ุงููุญูุฏ ูู ููุธ ุชุนุฑููุงุช ุงููููุฏ ุจูู ุงูุฅุตุฏุงุฑุงุช ุงูููุงุณูุฉ:
ูููู ุงููุงูุจ ูุง ูุฒุงู ูู ููุณู:
template< typename T, IsSigned< T > = true >
ูู C ++ 98 ุงููุฏูู
ุงูุฌูุฏ ุ ูุง ุชูุฌุฏ ุฃุณู
ุงุก ู
ุณุชุนุงุฑุฉ ูููุงูุจ ุ ุจุงูุฅุถุงูุฉ ุฅูู ุฐูู ุ ูุง ูู
ูู ุฃู ุชุญุชูู ููุงูุจ ุงููุธุงุฆู ุนูู ุฃููุงุน ุฃู ููู
ุงูุชุฑุงุถูุฉ. ูู
ูููุง ุฅุฏุฑุงุฌ ููุฏ SFINAE ุงูุฎุงุต ุจูุง ูู ููุน ุงููุชูุฌุฉ ุฃู ููุท ูู ูุงุฆู
ุฉ ู
ุนูู
ุงุช ุงููุธููุฉ. ููุตู ุจุงูุฎูุงุฑ ุงูุซุงูู ูุฃู ุงูู
ูุดุฆุงุช ูุง ุชุญุชูู ุนูู ุฃููุงุน ุงููุชุงุฆุฌ. ุฃูุถู ู
ุง ูู
ูููุง ูุนูู ูู ุดูุก ู
ุซู ูุฐุง:
template< typename T > T myAbs( T val, typename my_enable_if< my_is_signed< T >::value, bool >::type = true ) { return( ( val <= -1 ) ? -val : val ); }
ููุท ููู
ูุงุฑูุฉ - ุงููุณุฎุฉ ุงูุญุฏูุซุฉ ู
ู C ++:
template< typename T, IsSigned< T > = true > T myAbs( T val ) { return( ( val <= -1 ) ? -val : val ); }
ุฅุตุฏุงุฑ C ++ 98 ูุจูุญ ุ ููุฏู
ู
ุนูู
ุฉ ูุง ู
ุนูู ููุง ุ ูููู ูุนู
ู - ูู
ููู ุงุณุชุฎุฏุงู
ูุง ุฅุฐุง ูุงูุช ุถุฑูุฑูุฉ ููุบุงูุฉ. ููุนู
: ูุฌุจ ุชุทุจูู
my_enable_if
ู
my_is_signed
(
std :: enable_if std :: is_signed
ูุงูุช ุฌุฏูุฏุฉ ูู
std :: enable_if std :: is_signed
C ++ 11).
ุงูุญุงูุฉ ุงูุญุงููุฉ
C ++ 17 ุงูู
ูุฏู
ุฉ
if constexpr
ุ ุทุฑููุฉ
if constexpr
ู
ู ุงูุชุนููู
ุงุช ุงูุจุฑู
ุฌูุฉ ุงุณุชูุงุฏูุง ุฅูู ุงูุธุฑูู ูู ููุช ุงูุชุฑุฌู
ุฉ. ูุฌุจ ุฃู ุชููู ุนุจุงุฑุงุช if ูุฎูุงููุง ุตุญูุญุฉ ุจูุงุกู ุ ููู ุณูุชู
ุชูููู
ุงูุดุฑุท ูู ููุช ุงูุชุฑุฌู
ุฉ.
template< typename T > T myAbs( T val ) { if constexpr( std::is_signed_v< T > ) { return( ( val <= -1 ) ? -val : val ); } else { if constexpr( std::is_unsigned_v< T > ) { return val; } } }
ูู
ุง ูุฑู ุ ุฃุตุจุญุช ูุธููุฉ ุงูููู
ุฉ ุงูู
ุทููุฉ ูุฏููุง ุฃูุซุฑ ุฅุญูุงู
ุง ูุณูููุฉ ูู ุงููุฑุงุกุฉ. ูู
ุน ุฐูู ุ ูุฅู ุงูุชุนุงู
ู ู
ุน ุงูุฃููุงุน ุบูุฑ ุงูู
ุทุงุจูุฉ ููุณ ุณููุงู. ุฅู
static_assert
ุบูุฑ ุงูู
ุดุฑูุท ูุฌุนู ูุฐุง ุงูุจูุงู ุซุงุจุชูุง ุฅูู ุญุฏ ู
ุง ุ ููู ุฃู
ุฑ ู
ุญุธูุฑ ุจู
ูุฌุจ ุงูู
ุนูุงุฑ ุ ุจุตุฑู ุงููุธุฑ ุนู
ุง ุฅุฐุง ูุงู ูุชู
ุชุฌุงููู ุฃู
ูุง.
ูุญุณู ุงูุญุธ ุ ููุงู ุซุบุฑุฉ: ูู ูุงุฆูุงุช ุงูููุงูุจ ุ ูุง ูุชู
ุฅูุดุงุก ุนูุงู
ู ุงูุชุดุบูู ุงูู
ุณูุทุฉ ุฅุฐุง ูุงูุช ุงูุญุงูุฉ ู
ุณุชููุฉ ุนู ุงูููู
ุฉ. ! ู
ู
ุชุงุฒ
ูุจุงูุชุงูู ูุฅู ุงูู
ุดููุฉ ุงููุญูุฏุฉ ูู ุงูููุฏ ูู ุฃููุง ุชุชุนุทู ุฃุซูุงุก ุชุนุฑูู ุงููุงูุจ. ุฅุฐุง ุงุณุชุทุนูุง ุฅุฑุฌุงุก ุชูููู
static_assert
ุญุชู ููุช ุฅูุดุงุก ุงููุงูุจ ุ ูุณูุชู
ุญู ุงูู
ุดููุฉ: ุณูุชู
ุฅูุดุงุคู ุฅุฐุง ูุงูุช ุฌู
ูุน ุดุฑูุทูุง ุฎุงุทุฆุฉ ูููุท. ูููู ููู ูู
ูููุง ุชุฃุฌูู
static_assert
ุญุชู ูุชู
ุฅูุดุงุก ุงููุงูุจุ ุฌุนู ุญุงูุชูุง ุชุนุชู
ุฏ ุนูู ููุน!
template< typename > inline constexpr bool dependent_false_v{ false }; template< typename T > T myAbs( T val ) { if constexpr( std::is_signed_v< T > ) { return( ( val <= -1 ) ? -val : val ); } else { if constexpr( std::is_unsigned_v< T > ) { return val; } else { static_assert( dependent_false_v< T >, "Unsupported type" ); } } }
ุนู ุงูู
ุณุชูุจู
ูุญู ุจุงููุนู ูุฑูุจูู ุจุงููุนู ุ ููููุง ุจุญุงุฌุฉ ุฅูู ุงูุงูุชุธุงุฑ ุจุนุถ ุงูููุช ุญุชู ูุฃุชู C ++ 20 ุจุงูุญู ุงูููุงุฆู: ุงูู
ูุงููู
! ุณูุคุฏู ูุฐุง ุฅูู ุชุบููุฑ ุทุฑููุฉ ุงุณุชุฎุฏุงู
ุงูููุงูุจ (ู SFINAE) ุชู
ุงู
ูุง.
ุจุงุฎุชุตุงุฑ: ูู
ูู ุงุณุชุฎุฏุงู
ุงูู
ูุงููู
ููุญุฏ ู
ู ู
ุฌู
ูุนุฉ ุงููุณุงุฆุท ุงูุชู ูุชู
ูุจูููุง ูู
ุนูู
ุงุช ุงููุงูุจ. ุจุงููุณุจุฉ ููุธููุฉ ุงูููู
ุฉ ุงูู
ุทููุฉ ูุฏููุง ุ ูู
ูููุง ุงุณุชุฎุฏุงู
ุงูู
ูููู
ุงูุชุงูู:
template< typename T > concept bool Arithmetic() { return std::is_arithmetic_v< T >; }
ูููู ูู
ูููุง ุงุณุชุฎุฏุงู
ุงูู
ูุงููู
ุ ููุงู ุซูุงุซ ุทุฑู:
ูุงุญุธ ุฃู ุงููู
ูุฐุฌ ุงูุซุงูุซ ูุง ูุฒุงู ูุนูู ุนู ูุธููุฉ ุงููุงูุจ! ููู
ุง ููู ุงูุชูููุฐ ุงููุงู
ู ูู myAbs ูู ุงูุฅุตุฏุงุฑ C ++ 20:
template< typename T > concept bool Arithmetic() { return std::is_arithmetic_v< T >; } Arithmetic myAbs( Arithmetic val ) { if constexpr( std::is_signed_v< decltype( val ) > ) { return( ( val <= -1 ) ? -val : val ); } else { return val; } } int main() { unsigned int a{ myAbs( 5u ) }; int b{ myAbs< int >( 5u ) };
ู
ูุงูู
ุฉ ุชู
ุงูุชุนููู ุนูููุง ุชุนุทู ุงูุฎุทุฃ ุงูุชุงูู:
error: cannot call function 'auto myAbs(auto:1) [with auto:1 = const char*]' constraints not satisfied within 'template<class T> concept bool Arithmetic() [with T = const char*]' concept bool Arithmetic(){ ^~~~~~~~~~ 'std::is_arithmetic_v' evaluated to false
ุฃุญุซ ุงูุฌู
ูุน ุนูู ุงุณุชุฎุฏุงู
ูุฐู ุงูุฃุณุงููุจ ุจุฌุฑุฃุฉ ูู ุดูุฑุฉ ุงูุฅูุชุงุฌ ุ ููุช ุงูุชุฌู
ูุน ุฃุฑุฎุต ู
ู ููุช ุงูุชุดุบูู. SFINAEing ุณุนูุฏ!