如何从C++中的依赖类型中获得它所依赖的类型

How to get the type of what it depends on from a dependent type in C++

本文关键字:依赖 类型 C++      更新时间:2023-10-16

假设我在类型Container中定义了一个类型iterator,那么这种类型的对象就是Container::iterator。如何获取它所依赖的类型,即Container

struct Container
{
struct iterator {};
};
template<typename Cont>
auto getContainer(typename Cont::iterator&& iter)
{
return Cont{}; //return an empty container from the iterator, but type of Cont canNOT be deduced :(
}
//example
std::vector<int> v;
auto v2=getContainer(v.begin());

这是我在这里发现的一个广义问题:从C++(STL(中的迭代器类型获取容器类型但既然它已经有10年的历史了,我敢打赌可能会有一些神奇的解决方案。

编辑:我将问题推广到一个依赖类型,而不是容器,其中有人可能建议std::vector<T>::iterator实现为指针

假设有一些类型,所有类型都在中定义了一个公共typename

struct Something { struct SomeInnerType{}; };
struct SomeOtherThing { struct SomeInnerType{}; };
template<typename Thing>
auto getDepend(typename Thing::SomeInnerType&& obj)
{                       //^ why this can't be deduced (EDIT2)
return Thing{};
}

第二版:为什么Thing在这里不能推导,有什么原因吗?

如果你想从内部迭代器类型中推导出外部容器类型,你必须在迭代器中定义容器类型:

struct Container {
public:
struct iterator {
public:
using container_type = Container;
};
};

然后,您必须将迭代器类型传递给getContainer函数,而不是容器类型:

template <typename TIter>
TIter::container_type getContainer(TIter&& iter) {
return typename TIter::container_type {};
}

通过这种方式,您可以解决向模板提供请求的容器的问题:

int main() 
{
auto it = Container::iterator();
auto c = getContainer(std::move(it));
}

为什么Thing在这里无法推导,有什么原因吗?

因为这属于非推导上下文。

(重点矿井(

在以下情况下用于组成P不参与模板参数推导,但使用以下模板参数在别处推导的或明确规定的如果模板参数仅在非推导的上下文中使用,并且没有明确指定,模板参数推导失败

  1. 嵌套的名称说明符(作用域左侧的所有内容解析运算符::(合格id:

例如,

struct my_int_vector {
using iterator = std::vector<int>::iterator;
};

CCD_ 12和CCD_。然后

std::vector<int> v;
auto v2=getContainer(v.begin());                 // What should Thing be deduced as ?
auto v3=getContainer(my_int_vector::iterator{}); // What should Thing be deduced as ?

另一个样本可能是

struct my_int_vector {
using iterator = int*;
};
auto v3=getContainer(nullptr); // How could Thing be deduced as my_int_vector based on any information?