代码之家  ›  专栏  ›  技术社区  ›  Jacinto Resende

模板类型扣除失败?

  •  7
  • Jacinto Resende  · 技术社区  · 7 年前

    #include <type_traits>
    #include <iostream>
    using namespace std;
    
    template <typename T_> 
    using Integral = typename std::enable_if<std::is_integral<T_>::value,T_>::type;
    template <typename T_> 
    using NotIntegral = typename std::enable_if<!std::is_integral<T_>::value, T_>::type;
    
    template <typename T_>
    void printIt(const Integral<T_> &value) { cout << "Integral == " << value << endl; }
    
    template <typename T_>
    void printIt(const NotIntegral<T_> &value) { cout << "Non Integral == " << value << endl; }
    
    template <typename T_>
    void foo(const T_ &value) { printIt<T_>(value); }
    
    int main(int argc, char** argv)
    {
        printIt<int>(66);   //Must explicitly provide argument type.
        //printIt(33);        //Compiler error. No overloaded function....????
        foo(29.); 
    
        return 0;
    }
    

    为什么需要显式设置模板参数的类型?如果编译器发现它是一个 int 类型参数?

    1 回复  |  直到 7 年前
        1
  •  11
  •   Vittorio Romeo    7 年前

    为什么需要显式设置模板参数的类型?

    non-deduced contexts .

    想象一下专业化 std::enable_if<std::is_integral<T_>::value,T_> ::type 评估为其他内容。编译器无法从 typename something<T>::type T

    您可以通过放置 std::enable_if 作为返回类型的一部分,因此不匹配的重载被忽略:

    template <typename T>
    auto printIt(T x) -> std::enable_if_t<std::is_integral_v<T>, void> { /*...*/ }
    
    template <typename T>
    auto printIt(T x) -> std::enable_if_t<!std::is_integral_v<T>, void> { /*...*/ }
    

    live wandbox example