C++ 如何";“取消引用类型”;在C++;03?
如何在C++03中获得另一种类型的“取消引用类型”?请注意,它可以是其他可取消引用的类型,如C++ 如何";“取消引用类型”;在C++;03?,c++,templates,traits,template-meta-programming,c++03,C++,Templates,Traits,Template Meta Programming,C++03,如何在C++03中获得另一种类型的“取消引用类型”?请注意,它可以是其他可取消引用的类型,如std::vector::iterator e、 g.如果我有 template<typename T> struct MyPointer { T p; ??? operator *() { return *p; } }; 模板 结构MyPointer { tp; ?运算符*(){return*p;} }; 我如何确定用什么替换? (没有提升!我想知道如何自己解决。)模板
std::vector::iterator
e、 g.如果我有
template<typename T>
struct MyPointer
{
T p;
??? operator *() { return *p; }
};
模板
结构MyPointer
{
tp;
?运算符*(){return*p;}
};
我如何确定用什么替换?
(没有提升!我想知道如何自己解决。)模板
结构解除引用;
模板
结构解除引用
{
typedef typename T type;
};
模板
结构MyPointer
{
tp;
typename取消引用::类型运算符*(){return*p;}
};
您可以这样做,并且可以确保只有在向模板传递指针时,模板才会编译:
template<typename T>
struct MyPointer<T*>
{
T* p;
T operator*() { return *p; }
}
模板
结构MyPointer
{
T*p;
T运算符*(){return*p;}
}
在一般情况下,您不能。对于原始指针,您可以如其他答案所示进行部分专门化-自定义智能指针的结果类型可能有一个通用的typedef。但是,您不能编写一个函数来处理C++03中的任何指针。您可以使用一个简单的构造,递归地从给定类型中删除所有指针,如下所示:
template<typename T>
struct ActualType { typedef T type; };
template<typename T>
struct ActualType<T*> { typedef typename ActualType<T>::type type; };
模板
结构实际类型{typedef T type;};
模板
结构实际类型{typedef typename实际类型::type type;};
下面是内联包装函数,用于递归地从给定指针或非指针类型中找出实际值
template<typename T>
typename ActualType<T>::type ActualValue (const T &obj) { return obj; }
template<typename T>
typename ActualType<T>::type ActualValue (T *p) { return ActualValue(*p); }
模板
typename-ActualType::type-ActualValue(const T&obj){return obj;}
模板
typename ActualType::type ActualValue(T*p){返回ActualValue(*p);}
把它当作:
template<typename T>
struct MyPointer
{
T p;
typename ActualType<T>::type operator *() { return ActualValue(p); }
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
};
模板
结构MyPointer
{
tp;
typename ActualType::type运算符*(){返回实际值(p);}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
};
在本例中,它删除了给定类型中的所有指针,但您可以根据需要配置ActualType
和ActualValue
。即使使用非指针类型声明MyPointer
,也不会出现任何编译器错误
这是一个针对单指针和无指针类型的解决方案。@Paul:Mehrdad问如何取消引用类型,我提供了一个答案。@Mehrdad:当然可以,如果您提供非指针类型,编译器会抱怨。这看起来最好。但是,对于重载
运算符*
的类型呢?@Mehrdad:您希望您的程序使用重载运算符*
的非指针类型,还是希望这些类型的操作失败?是否有标准命名约定建议类型具有typedef值\类型/指针\类型/引用\类型,如果它重载了诸如*?如果你做出这样的假设,那么你就可以使用默认版本的尊重。如果他们不遵循这个惯例,你仍然会得到一个编译器错误(这两个方面都是最好的)。无论如何+1,@Mehrad是的,你可以。事实上你是肯定的。请看代码的第二行,看看模板的专门化。我的意思是,在我的示例中,您不能假设p
是指针。这可能只是因为p
的运算符*
过载了。这似乎是正确的答案,但我并不希望如此。:)谢谢@DeadMG:返回类型不能是typename std::iterator\u traits::value\u type
?传递给MyPointer
类的任何内容都可能会重载iterator\u traits
。这就是为什么您将同时知道指针类型T*p
和返回T运算符*()
@Tux-D的类型:因为您不能假定p
是指针。我一定是遗漏了什么。我的意思是,通过将T设置为指向的类型,可以显式地将其设置为指针。因此,您将p定义为“T*p”。@Tux-D Mehrdad说他不想将模板化类型仅限于指针,因为非指针类型也可能重载运算符*
。对于任何寻找C++11版本问题的人来说:但这有Paul Manta旧答案注释中描述的问题。它不适用于非指针类型的类型<代码>运算符*可以为非指针类型重载。@jogojapan,它可以工作。查看编辑后的答案。这似乎是一种特殊情况,MyPointer
定义了它的操作符*
,它返回类型为ActualType::type
的对象。但是如果你有一个任意类,带有一个返回任意数据类型的操作符*
,你如何让它工作呢?@jogojapan,那么这将是一个编译器错误,我认为OP无意返回任意类型。必须结合使用ActualType
和ActualValue
,才能获得真实的对象类型和值。
template<typename T>
struct MyPointer
{
T p;
typename ActualType<T>::type operator *() { return ActualValue(p); }
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
};