Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何";“取消引用类型”;在C++;03?_C++_Templates_Traits_Template Meta Programming_C++03 - Fatal编程技术网

C++ 如何";“取消引用类型”;在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;} }; 我如何确定用什么替换? (没有提升!我想知道如何自己解决。)模板

如何在C++03中获得另一种类型的“取消引用类型”?请注意,它可以是其他可取消引用的类型,如
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); }
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^                       ^^^^^^^^^^^^^^
};