enable_if用于非模板化成员函数 [英] usage of enable_if for non-templated member function
问题描述
本书C ++编程语言(第四版)。第28.4节(第795页)解释了enable_if并给出了定义operator - >()条件的示例。书中的示例只是一个代码片段,我完成它到一个程序如下:
The book C++ Programming Language(fourth edition). Chapter 28.4 (page 796) explains enable_if and gives an example of making the definition of operator->() conditional. The example in the book is only a code snippet, and I completed it to a program as follows:
#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中编译。编译器报告错误:在'struct std :: enable_if'中没有名为'type'的类型
The code above doesn't compile in gcc 4.7.2. The compiler complains: error: no type named 'type' in 'struct std::enable_if'
根据本书中的解释,运算符 - >如果T不是类,则忽略。但是,这不解释编译错误。编译错误指示相反,即使T不是类,也不会忽略operator - >()的定义。编译错误似乎由此后 std :: enable_if有条件地解释编译成员函数。但是帖子似乎与书的解释不一致。任何人都可以帮助和解释enable_if的成员函数的用法?在上面的例子中,如果我想定义运算符 - >()只有当T是类,是否有一个干净,优雅的解决方案?谢谢。
According to the explanation in the book, the operator->() will be ignored if T is not a class. However, that doesn't explain the compiling error. The compiling error indicates the opposite, the definition of operator->() is not ignored even if T is not a class. The compiling error seems to be explained by this post std::enable_if to conditionally compile a member function . But the post seems inconsistent with the book explanation. Anyone can help and explain the usage of the enable_if for member function? In the above example, if I do want to define the operator->() only when T is class, is there a clean and elegant solution? Thank you.
非常感谢您的回复。还有另一种基于重载的解决方法(我不会说它比其他已发布的解决方案更好)
Thank you very much for the replies. There is another workaround based on overloading(I wouldn't say it's better than other posted solutions)
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);
推荐答案
首先,如@jrok和post你链接到:
你必须有一个模板函数使用 enable_if
。但在你的特定情况下它不是一个好主意,因为没有理由这样做 operator->
模板。此外,它不会工作! cuz没有办法实例化一个特定的运算符 - >()!它不具有(和不能)任何参数,并且没有语法在您在某些对象上调用时指定它!因此, T
(或whateve虚拟类型)将无法从此调用中推导出来。
first of all, as mentioned by @jrok and the post you linked to:
you have to have a template function to use enable_if
. but it is not a good idea in your particular case, because there is no reason to do this operator->
templated. moreover, it wouldn't work! cuz there is no way to instantiate a particular operator->()! it doesn't have (and can't) any parameters and there is no syntax to specify it when you call it on some object! so, T
(or whateve dummy type) will/could not be deduced from this call.
一个解决方法,你可以使用编译时条件继承。即smth这样:
so, as a workaround you may use compile-time conditional inheritance. i.e. smth like this:
template <typename T, bool IsClass>
struct smart_base
{
struct base {};
};
template <typename T>
struct smart_base<T, true>
{
struct base
{
T* operator->()
{
// do that ever you wanted to do
}
};
};
template <typename T>
struct smart : public smart_base<T, std::is_class<T>::value>::base
{
// depending on T here you have, or have no operator-> inherited
};
您必须明白, operator->
实际上在你的基类中将需要移动一些函数和/或数据成员到base-of-the-base类:)或者可以使用CRTP技术从基本类访问派生类的成员:)
you have to understand, that having operator->
actually in your base class will require to move some function and/or data members to base-of-the-base class :) or you may use CRTP technique to access members of a derived class from the base one :)
这篇关于enable_if用于非模板化成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!