【发布时间】:2020-06-19 02:38:49
【问题描述】:
一天半以来,我一直在苦苦挣扎,试图学习模板专业化和 std::enable_if()。我没有得到的东西。我试图根据编译时的类类型和用户规范来允许类方法的返回类型规范。例如,如果类类型是整数,我可能希望方法返回浮点类型(或整数)。
我的实际用例是一个数组,我对其中的所有值进行平均。我什至可能想要一个布尔返回值来反映二进制“投票”的结果。有很多组合。必须有一种方法可以做到这一点,而无需单独创建所有重载。我的示例代码是我能做到的最简单的。
如果有任何指点,我将不胜感激。如果确实是这样的话,我该如何进行这种部分专业化?
#include <string>
template <class T>
class Test {
public:
Test(T val) { val_ = val; }
template <typename U> U halve ();
private:
T val_;
};
template<class T> template<typename U>
U Test<T>::halve() {
throw std::invalid_argument("Cannot halve non-numeric objects");
}
template<class T> template<typename U> //example: T=int, U=float
typename std::enable_if_t<std::is_arithmetic<T>::value && std::is_arithmetic<U>::value, U>
Test<T>::halve() { //error C2244 - unable to match function definition to an existing declaration
return ((U)val_ / (U)2);
}
int main() {
Test<int> t1(5);
float f = t1.halve<float>(); //expect 2.5
int i = t1.halve<int>(); //expect 2
Test<std::string> t2((std::string)"blah");
int t2h = t2.halve<int>(); //this will throw (by design)
return 0;
}
【问题讨论】:
-
您不能在 C++ 中部分特化函数。差不多就是这样。你必须把它变成类的部分专业化。这基本上意味着将
halve()转变成一个瘦包装器,它调用辅助类中的真实方法,即来自template<typename T, typename U> class halve_helper的halve_helper<T,U>::real_halve(val_);,然后部分特化halve_helper。祝你好运。 -
谢谢山姆。这有助于我更好地理解我的问题几乎重复的最佳答案:link。我将尝试那里描述的两种方法(转化为你的方法,以及 kjpus 的建议),看看哪一种看起来更易读和可维护。