【发布时间】:2013-08-07 23:17:21
【问题描述】:
C++ 编程语言(第四版)一书。第 28.4 章(第 796 页)解释了 enable_if 并给出了使 operator->() 有条件的定义的示例。书中的例子只是一个代码sn-p,我完成成一个程序如下:
#include <iostream>
#include <type_traits>
#include <complex>
using namespace std;
template<bool B, typename T>
using Enable_if=typename std::enable_if<B,T>::type;
template<typename T>
constexpr bool Is_class(){ //the book example misses constexpr
return std::is_class<T>::value;
}
template<typename T>
class Smart_pointer{
public:
Smart_pointer(T* p):data(p){
}
T& operator*();
Enable_if<Is_class<T>(),T>* operator->(){
return data;
}
~Smart_pointer(){
delete data;
}
private:
T* data;
};
int main()
{
Smart_pointer<double> p(new double); //compiling error in g++ 4.7.2: no type named 'type' in 'struct std::enable_if<false, double>'
//Smart_pointer<std::complex<double>> q(new std::complex<double>);//compile successfully.
}
上面的代码不能在 gcc 4.7.2 中编译。编译器报错:error: no type named 'type' in 'struct std::enable_if'
根据书中的解释,如果 T 不是类,operator->() 将被忽略。但是,这并不能解释编译错误。编译错误表明相反,即使 T 不是类,也不会忽略 operator->() 的定义。这篇文章std::enable_if to conditionally compile a member function 似乎解释了编译错误。但该帖子似乎与书中的解释不一致。任何人都可以帮助解释成员函数的 enable_if 的用法吗?在上面的例子中,如果我只想在 T 是类时定义 operator->(),有没有一个干净优雅的解决方案?谢谢你。
非常感谢您的回复。还有另一种基于重载的解决方法(我不会说它比其他发布的解决方案更好)
template<typename T>
T* Smart_pointer<T>::operator->(){
op_arrow(std::integral_constant<bool,Is_class<T>()>());
}
private:
T* op_arrow(std::true_type){
return data;
}
T* op_arrow(std::false_type);
【问题讨论】:
-
您链接到的帖子很好地解释了它 - 这仅在函数本身是模板时才有效。