【问题标题】:Template type deduction fails?模板类型扣除失败?
【发布时间】:2018-02-19 10:58:04
【问题描述】:

考虑以下示例。

#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 类型参数?

【问题讨论】:

    标签: c++ c++11 templates typetraits type-deduction


    【解决方案1】:

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

    因为这些是non-deduced contexts。

    想象一下专门化std::enable_if&lt;std::is_integral&lt;T_&gt;::value,T_&gt; 以便::type 评估为别的东西。编译器无法知道从typename something&lt;T&gt;::type 到T 的映射。

    您可以通过将std::enable_if 作为返回类型的一部分来实现您想要的结果,这样不匹配的重载就会被 SFINAE 淘汰:

    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

    【讨论】:

      猜你喜欢
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      相关资源
      最近更新 更多