模板类型扣除失败?

时间:2017-09-11 08:52:16

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

考虑以下示例。

#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 个答案:

答案 0 :(得分:11)

  

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

因为这些是non-deduced contexts

想象一下专门化let gradient = CAGradientLayer() var gradientSet = [[CGColor]]() var currentGradient: Int = 0 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) gradientSet.append([gradientOne, gradientTwo]) gradientSet.append([gradientTwo, gradientThree]) gradientSet.append([gradientThree, gradientOne]) gradient.frame = self.tableView.bounds gradient.colors = gradientSet[currentGradient] gradient.startPoint = CGPoint(x:0, y:0) gradient.endPoint = CGPoint(x:1, y:1) gradient.drawsAsynchronously = true tableView.layer.insertSublayer(gradient, at: 0) animateGradient() } func animateGradient() { if currentGradient < gradientSet.count - 1 { currentGradient += 1 } else { currentGradient = 0 } let gradientChangeAnimation = CABasicAnimation(keyPath: "colors") gradientChangeAnimation.delegate = self gradientChangeAnimation.duration = 5.0 gradientChangeAnimation.toValue = gradientSet[currentGradient] gradientChangeAnimation.fillMode = kCAFillModeForwards gradientChangeAnimation.isRemovedOnCompletion = false gradient.add(gradientChangeAnimation, forKey: "colorChange") } func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { if flag { gradient.colors = gradientSet[currentGradient] animateGradient() } } ,以便std::enable_if<std::is_integral<T_>::value,T_>评估其他内容。编译器无法知道从::typetypename something<T>::type的映射。

您可以将T作为返回类型的一部分来实现所需的结果,以便不匹配的重载是SFINAEd:

std::enable_if

live wandbox example