【发布时间】:2017-01-16 00:28:02
【问题描述】:
我试图更好地理解 C++11 中的 std::enable_if,并一直在尝试编写一个最小的示例:一个类 A 具有一个成员函数 void foo(),它根据类型具有不同的实现T 来自类模板。
下面的代码给出了预期的结果,但我还没有完全理解它。为什么版本V2 可以工作,而V1 不行?为什么需要“冗余”类型U?
#include <iostream>
#include <type_traits>
template <typename T>
class A {
public:
A(T x) : a_(x) {}
// Enable this function if T == int
/* V1 */ // template < typename std::enable_if<std::is_same<T,int>::value,int>::type = 0>
/* V2 */ template <typename U=T, typename std::enable_if<std::is_same<U,int>::value,int>::type = 0>
void foo() { std::cout << "\nINT: " << a_ << "\n"; }
// Enable this function if T == double
template <typename U=T, typename std::enable_if<std::is_same<U,double>::value,int>::type = 0>
void foo() { std::cout << "\nDOUBLE: " << a_ << "\n"; }
private:
T a_;
};
int main() {
A<int> aInt(1); aInt.foo();
A<double> aDouble(3.14); aDouble.foo();
return 0;
}
是否有更好的方法来实现所需的结果,即基于类模板参数对 void foo() 函数进行不同的实现?
【问题讨论】:
-
您的示例不适合使用
enable_if。简单的重载可以解决你的问题。enable_if主要用于 deduced 模板参数。 -
使用
std::enable_if将适合于将推导的浮点 类型与integral 类型分开。像这样的两种特定类型更适合重载。 -
@KerrekSB @WhozCraig 在这种特殊情况下我将如何超载?通过使用类外定义
void A<int>::foo() {}和void A<double>::foo() {}?我的意图是最终代码仅包含所需的函数版本(即,如果从未调用过这样的函数,则没有函数A<double>::foo()) -
据我了解,问题是关于为什么以及如何冗余的
typename U=T使示例工作,但并非没有它。有人解释一下吗?
标签: c++ c++11 void sfinae enable-if