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

如何从C++中依赖类型获得依赖于它的类型,c++,templates,C++,Templates,假设我在类型容器中定义了一个类型迭代器,那么这种类型的对象将是Container::iterator。如何获取它所依赖的类型,即容器 结构容器 { 结构迭代器{}; }; 样板 auto getContainertypename Cont::迭代器(&iter) { return Cont{};//从迭代器返回空容器,但无法推断Cont的类型: } //范例 std::向量v; auto v2=getContainerv.begin; 这是我在这里发现的一个广义问题: 但既然它已经有10年的历史

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

结构容器 { 结构迭代器{}; }; 样板 auto getContainertypename Cont::迭代器(&iter) { return Cont{};//从迭代器返回空容器,但无法推断Cont的类型: } //范例 std::向量v; auto v2=getContainerv.begin; 这是我在这里发现的一个广义问题: 但既然它已经有10年的历史了,我打赌可能会有一些神奇的解决办法

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

假设有一些类型,它们都在内部定义了一个公共类型名


EDIT2:为什么这里的东西不能推断,有什么原因吗?

如果要从内部迭代器类型中推断外部容器类型,必须在迭代器中定义容器类型:

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 {};
}

如果要从内部迭代器类型中扣除外部容器类型,则必须在迭代器中定义容器类型:

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 {};
}
为什么这里的事情无法推断,有什么原因吗

因为这是属于我的

重点矿山

在以下情况下,类型、模板和非类型值 用于组合P不参与模板参数 演绎,但使用的模板参数是 在别处推导或明确指定。如果模板参数为 仅在非推断上下文中使用,未明确指定, 模板参数推断失败

嵌套的名称说明符包含范围左侧的所有内容 解析运算符::使用 合格id: 比如说,

struct my_int_vector {
    using iterator = std::vector<int>::iterator;
};
另一个样本可能是

struct my_int_vector {
    using iterator = int*;
};
auto v3=getContainer(nullptr); // How could Thing be deduced as my_int_vector based on any information?
为什么这里的事情无法推断,有什么原因吗

因为这是属于我的

重点矿山

在以下情况下,类型、模板和非类型值 用于组合P不参与模板参数 演绎,但使用的模板参数是 在别处推导或明确指定。如果模板参数为 仅在非推断上下文中使用,未明确指定, 模板参数推断失败

嵌套的名称说明符包含范围左侧的所有内容 解析运算符::使用 合格id: 比如说,

struct my_int_vector {
    using iterator = std::vector<int>::iterator;
};
另一个样本可能是

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

你说得到是什么意思?类型信息应该具有什么形状?你想如何使用它?不,它和10年前一样。我认为这通常是不可能的。例如,连续容器的迭代器(如std::vector)可以简单地实现为指针。如何从普通指针中提取有关容器的信息@Carsten这显然不是我使用getContainer的目的,因为您显式地专门化了类型。我想要一个自动扣除的解决方案你说的“得到”是什么意思?类型信息应该具有什么形状?你想如何使用它?不,它和10年前一样。我认为这通常是不可能的。例如,连续容器的迭代器(如std::vector)可以简单地实现为指针。如何从普通指针中提取有关容器的信息@Carsten这显然不是我使用getContainer的目的,因为您显式地专门化了类型。我想要一个自动扣除的解决方案,是的,这解决了问题,但是你能解释一下关于我的EDIT2,这种依赖模板扣除限制的原因吗当然!当显式调用该函数时,您将编写以下代码:getContainerstd::moveit;。但是,此参数可以从参数列表中隐式扣除,因此可以忽略它。在您的示例中,getContainer的定义方式需要知道从中扣除迭代器的容器类型,但是,正如注释中所述,如果容器使函数无法达到从迭代器中扣除容器的目的,则需要知道从中扣除迭代器的容器类型。要做到这一点,您需要提供迭代器并使其声明它的容器。向上投票,是的,这解决了问题,但您能否解释一下有关my EDIT2的一点,这种依赖模板推断限制的原因当然!当显式调用该函数时,您将编写以下代码:getContainerstd::moveit;。但是,此参数可以从参数列表中隐式扣除,因此可以忽略它。在您的示例中,getContainer的定义方式需要知道从中扣除迭代器的容器类型- 然而,正如注释中所述,提供容器make会破坏函数的目的,即从迭代器中扣除容器。要做到这一点,您需要提供迭代器并使其声明其容器。