【发布时间】:2016-10-10 19:59:40
【问题描述】:
我想确定某物是否是容器。现在我正在格式化为具有类型和分配器的容器上对其进行测试。我的最终目标是学习如何编写一个容器模板,该模板在包含自身层时可以允许对其最里面的元素进行直接迭代。例如。如果有一个包含 3 个容器的容器,每个容器又包含 3 个容器,每个容器包含 3 个元素,我希望能够在一个基于 for 循环的范围内遍历所有 27 个元素。区分某物是直接包含元素的容器还是包含元素容器(或容器容器......元素容器)的容器,使用 SFINAE 检查元素是否具有迭代器似乎是确定 @987654321 @ 函数应该将迭代器返回到元素或所述元素的 begin() 函数的结果。如果我的第一步可以开始工作,我想将该逻辑包含在编写容器中,但我无法编译它:
#include <vector>
#include <iostream>
template <typename T,
template <typename E, typename Allocator = std::allocator<E>> class Container
>
void is_cont(typename Container<T>::iterator it)
{
std::cout << "is iterator\n";
}
template <typename T,
template <typename E, typename Allocator = std::allocator<E>> class Container
>
void is_cont(Container<T>& cont)
{
std::cout << "is container\n";
}
int main()
{
std::vector<int> vec{ 2, 4, 6 };
is_cont(vec); // Output: "is container"
//is_cont(vec.begin()); // COMPILER ERROR
}
我该如何解决这个问题?
【问题讨论】:
-
给定迭代器
vec.begin()(很可能只是一个int*),编译器无法实例化每个可能的 Container 类来查看该迭代器是否恰好属于该类型Container<T>::iterator。即使可以,它也可能是模棱两可的。您必须明确指定函数的模板参数。 -
@Kundor 如果
vec.begin()是int*,那不是还有std::vector<int>::iterator,区别在于int*是typedef?似乎用std::vector<Bar> vec(3, Bar{});替换std::vector<int> vec{ 2, 4, 6 };行,其中Bar是一个空虚拟struct给出了相同的错误。 -
是的。所以?给定一个函数调用
is_cont(int*),编译器应该推断出模板参数。因此,您要求它从int*向后工作以查找具有成员typedefiterator的类型,即int*。当然,您可以看到这是行不通的(一方面,由于这些是模板类,因此必须检查实际上是无限的可能性)。
标签: c++ templates iterator containers sfinae