1

テンプレートの動作を使用std::numeric_limits<T>::is_integerして変更する方法はありますか?std::numeric_limits<T>::is_specialized

たとえば、これを行うことができます:

template < typename T >
void foo( const T& bar )
{
    if( std::numeric_limits< T >::is_integer )
    {
        isInt( bar );
    }
    else if( std::numeric_limits< T >::is_specialized )
    {
        isFloat( bar );
    }
    else
    {
        isString( bar );
    }
}
4

2 に答える 2

8

お持ちのものは現在有効です。<type_traits>ただし、分岐条件 (最適化されている場合とされていない場合があります) に依存するのではなく、型に基づいて別の関数にディスパッチされるため、代わりにSFINAE を使用することをお勧めします。

を使用std::enable_ifして次のことができます。

template<typename T, 
         typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& t) {
    isInt(t);
}

template<typename T, 
         typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isFloat(t);
}

template<typename T, 
         typename std::enable_if<!std::is_integral<T>::value && 
                                 !std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isString(t);
}

ライブデモ

enable_ifの 2 番目のパラメーターが に設定されている理由は、int入力の手間を省くためです。が省略されている場合は、入力する文字数を節約できるように設定するだけでなく、int実行する必要があります。それらはすべての意図と目的で同等です。typename = typename std::enable_if<std::is_integral<T>::value>::type0

于 2014-08-11T20:07:15.573 に答える
4

「明らかな」答えは、のようなものを使用できるということですstd::enable_if

例えば:

template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type
    foo(const T &bar) { isInt(bar); }
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_specialized, void>::type
    foo(const T &bar) { isFloat(bar); }

このアプローチの問題は、これが (例として)intパラメーターに対してあいまいであることnumeric_limits<int>::is_specialized == trueです。

numeric_limitsこれを解決するには、個人的に, よりも優れた特性を使用します。ブール条件を使用して、必要な正確な条件をテストすることもできます。

template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_integer, void>::type
    foo(const T &bar) { isFloat(bar); }
于 2014-08-11T20:07:27.960 に答える