9

C++(11) の使用方法を理解しようとしています<type_traits>

これが私の簡単なテストプログラムです

#include <type_traits>

template<class U, class S>
inline U add(typename std::enable_if<std::is_unsigned<U>::value,U>::type a,
             typename std::enable_if<std::is_signed  <S>::value,S>::type b)
{
    return a + b;
}

int main(int argc, const char * argv[], const char * envp[])
{
    unsigned int ui;
    int i;
    auto a = add(ui, i);
    return 0;
}

GCC 4.8.1 でコンパイルすると、次のエラーが発生します。

/home/per/f.cpp: In function ‘int main(int, const char**, const char**)’:
/home/per/f.cpp:15:23: error: no matching function for call to ‘add(unsigned int&, int&)’
     auto a = add(ui, i);
                       ^
/home/per/f.cpp:15:23: note: candidate is:
/home/per/f.cpp:5:10: note: template<class U, class S> U add(typename std::enable_if<std::is_unsigned<U>::value, U>::type, typename std::enable_if<std::is_signed<S>::value, S>::type)
 inline U add(typename std::enable_if<std::is_unsigned<U>::value,U>::type a,
          ^
/home/per/f.cpp:5:10: note:   template argument deduction/substitution failed:
/home/per/f.cpp:15:23: note:   couldn't deduce template parameter ‘U’
     auto a = add(ui, i);
                       ^

GCC がテンプレート パラメータを推測できない理由がわかりませんU。私のコードに欠落している情報は誰でも知っています。つまり、最初の引数として符号なし整数型を受け取り、2 番目の引数として符号付き整数型を取る C++11 でプログラムを作成する方法です。

4

5 に答える 5

8

Uコンパイラにandを推測する機会を与えていませんS。関数を次のように書き換えて、SFINAE チェックをテンプレート パラメーター リストに移動できます。

template<class U, class S,
    typename std::enable_if<std::is_unsigned<U>::value &&
                            std::is_signed  <S>::value
        >::type* = nullptr>
inline U add(U a, S b)
{
    return a + b;
}

これが実際のです。

于 2013-06-07T14:19:41.227 に答える
4

型について推論する前に、まず型を推測する必要があります!

そのはず:

template <typename U, typename S>
typename std::enable_if<std::is_unsigned<U>::value &&
                        std::is_signed<S>::value>, U>::type
add(U u, S s)
{
    // ...
}
于 2013-06-07T14:19:29.260 に答える
2

「ネストされた typedef」式からテンプレート パラメーターを推測することはできません。つまり、 からは推測できますが、Uから は推測できsome_template<U>ませんsome_template<U>::type

コンパイラは、すべての (無限の!) インスタンス化を列挙some_templateして、ネストされた typedef が実際の引数の型と等しいものを確認することはできません。

于 2013-06-07T14:17:29.087 に答える