如何为自定义容器的迭代器重载模板函数
How to make an overload for templated functions for a custom container's iterator
这是一个关于模板的通用问题,我以 advance 为例。假设有一些原因我不能在这里使用 ADL 或隐藏的朋友。
std::advance
的定义是:
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );
为了争论,假设我有一个容器 H,带有迭代器,由于某种原因我想重载 std::advance
for:
template <typename T, class Allocator=std::allocator<T>>
class H
{
// etc
class iterator;
};
如何设计一个 advance 重载来匹配该迭代器,并在 H 的迭代器 class 上调用 advance 时让 C++ 正确 select 重载?下面的代码不起作用,因为在模板中只指定了 H,而不是迭代器本身:
template< template <typename, class> class container, class T, class Allocator, class Distance >
constexpr void advance( container<T, Allocator>::iterator& it, Distance n );
我不太明白如何在模板行中具体指定迭代器。
我的一个朋友想出了一个基于标签(空结构)的解决方案。
基本上,在迭代器中放置一个唯一的空结构 class 然后使用它构建一个 C++20 概念,然后使用它来匹配模板重载:
template <typename T, class A = std::allocator<T>>
class H
{
// etc
public:
class iterator
{
public:
struct cheat_tag {};
// etc
};
};
template<class T>
concept h_iterator = requires { typename T::cheat_tag; };
namespace std
{
template <h_iterator T, class D>
constexpr void advance(T&, D)
{
// etc
}
}
如果您匹配您尝试重载的模板的签名完全,这应该有效。
这是一个关于模板的通用问题,我以 advance 为例。假设有一些原因我不能在这里使用 ADL 或隐藏的朋友。
std::advance
的定义是:
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );
为了争论,假设我有一个容器 H,带有迭代器,由于某种原因我想重载 std::advance
for:
template <typename T, class Allocator=std::allocator<T>>
class H
{
// etc
class iterator;
};
如何设计一个 advance 重载来匹配该迭代器,并在 H 的迭代器 class 上调用 advance 时让 C++ 正确 select 重载?下面的代码不起作用,因为在模板中只指定了 H,而不是迭代器本身:
template< template <typename, class> class container, class T, class Allocator, class Distance >
constexpr void advance( container<T, Allocator>::iterator& it, Distance n );
我不太明白如何在模板行中具体指定迭代器。
我的一个朋友想出了一个基于标签(空结构)的解决方案。
基本上,在迭代器中放置一个唯一的空结构 class 然后使用它构建一个 C++20 概念,然后使用它来匹配模板重载:
template <typename T, class A = std::allocator<T>>
class H
{
// etc
public:
class iterator
{
public:
struct cheat_tag {};
// etc
};
};
template<class T>
concept h_iterator = requires { typename T::cheat_tag; };
namespace std
{
template <h_iterator T, class D>
constexpr void advance(T&, D)
{
// etc
}
}
如果您匹配您尝试重载的模板的签名完全,这应该有效。