C++ 解释cppreference.com中关于迭代器标记的示例代码
有人能给我解释一下参考网站样本中的几点吗? 该技术描述函数重载依赖于迭代器类型。 前两个带有“using”的typedef很容易理解。 这些问题与alg功能有关:C++ 解释cppreference.com中关于迭代器标记的示例代码,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,有人能给我解释一下参考网站样本中的几点吗? 该技术描述函数重载依赖于迭代器类型。 前两个带有“using”的typedef很容易理解。 这些问题与alg功能有关: 在模板参数列表中,没有参数名的“typename=…”是否意味着使用了默认值而无法在函数调用中覆盖此值 我是否正确理解第二个模板参数的用法?只有在传递的迭代器类型和期望的迭代器标记的类型相等的情况下才会生成函数 请您解释一下第二个函数alg中第三个模板参数的用法和注释: “typename=void>//避免模板重新定义错误的伪值
模板
使用EnableIf_t=typename std::enable_if::type;
模板
使用IsSameIteratorCond=
std::是相同的;
模板<
类型名BDIter,
typename=EnableIf\u t>
无效alg(BDIter,BDIter)
{
std::cout//伪值以避免模板重新定义错误
无效alg(雷特,雷特)
{
标准::cout
否,用户可以覆盖参数。正在命名参数
是可选的。如果不使用它,则不必这样做
是。标记必须等于std::双向迭代器\u标记
对于要启动的第一个重载,以及
第二个
如果没有第三个模板参数,则
函数声明将是相同的,这是非法的
两者都必须根据参数、返回类型、名称或模板而有所不同
参数(这里就是这种情况)
typename=…
声明了一个未命名的模板参数。客户端代码仍然可以覆盖该参数,但该参数不能在函数定义中使用。此处使用该参数是因为第二个模板参数用于利用SFINAE,而不是计算出要在定义中使用的类型
正确,如果迭代器类型与预期类型不同,则该函数将从重载候选集中删除
需要伪参数,因为默认值不是模板签名的一部分,所以两个版本的alg
将尝试定义相同的函数模板
使用默认值和伪参数对我来说非常难看,我更喜欢使用标记分派:
template<typename BDIter>
void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
{
std::cout << "alg() called for bidirectional iterator\n";
}
template <typename RAIter>
void alg(RAIter, RAIter, std::random_access_iterator_tag)
{
std::cout << "alg() called for random-access iterator\n";
}
template <typename It>
void alg(It a, It b)
{
return alg(a, b, typename std::iterator_traits<It>::iterator_category{});
}
模板
void alg(BDIter,BDIter,std::双向迭代器标记)
{
std::谢谢。不知道“默认值不是模板签名的一部分,”你能在C++标准或CPPISTY站点上给我一个链接吗?我找不到简洁的引用,但是想想函数声明中的模拟;如果函数只在默认参数中不同,它们显然试图声明一个具有相同签名的函数。@ AMIGO421这里有一些很好的讨论(但不是简洁的)!:这是一篇关于模板默认参数的专家级论文:
template<typename BDIter>
void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
{
std::cout << "alg() called for bidirectional iterator\n";
}
template <typename RAIter>
void alg(RAIter, RAIter, std::random_access_iterator_tag)
{
std::cout << "alg() called for random-access iterator\n";
}
template <typename It>
void alg(It a, It b)
{
return alg(a, b, typename std::iterator_traits<It>::iterator_category{});
}