Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不明确的函数重载[例如max()] 有可能重载C++中具有相似但不同模板签名的函数。< /P>_C++_Algorithm_Function_Templates_Overloading - Fatal编程技术网

不明确的函数重载[例如max()] 有可能重载C++中具有相似但不同模板签名的函数。< /P>

不明确的函数重载[例如max()] 有可能重载C++中具有相似但不同模板签名的函数。< /P>,c++,algorithm,function,templates,overloading,C++,Algorithm,Function,Templates,Overloading,考虑max()函数。如果我想要一个max()函数,它可以包含以下三个选项:int,*int范围,int迭代器范围 STL将此功能分为两个功能: 你能不能在C++中实现这个行为?如果是这样,怎么?< /P> 编辑:这将使max(vec.begin(),vec.end())和max(向量[0],向量[1])编译成功并找到范围的最大值和两个传递对象的最大值。我个人认为不可能在STL中组合这两个函数,但我要确认这是不可行的。现在重载是不明确的,因为您没有限制它们。编译器如何知道第一个不应该用于迭

考虑max()函数。如果我想要一个
max()
函数,它可以包含以下三个选项:
int
*int
范围,
int
迭代器范围

STL将此功能分为两个功能:

<>你能不能在C++中实现这个行为?如果是这样,怎么?< /P>
编辑:这将使
max(vec.begin(),vec.end())
max(向量[0],向量[1])编译成功并找到范围的最大值和两个传递对象的最大值。我个人认为不可能在STL中组合这两个函数,但我要确认这是不可行的。

现在重载是不明确的,因为您没有限制它们。编译器如何知道第一个不应该用于迭代器

答案很简单,你必须说出来。幸运的是,该标准定义了您可以查询的关于您传递给它的迭代器类型的各种信息,只要它是迭代器即可

最后一点是关键:如果
std::iterator_标记
没有嵌套的typedef
iterator_类别
,那么
t
不是迭代器。因此,我们可以使用定义一个自定义特征来检查给定类型是否是迭代器

在代码中,它如下所示:

// C++17 void_t
template <typename...>
using void_t = void;

template <typename T, typename = void>
struct is_iterator : std::false_type {
};

template <typename T>
struct is_iterator<T, void_t<typename std::iterator_traits<T>::iterator_category>> : std::true_type {
};

template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;

您还可以在上找到工作示例。

是的,这是可能的。你试过了吗?你在哪里遇到了麻烦?只要函数调用不干扰同名函数调用,你就不应该有任何重载问题。你不能实现一个看起来像
int max(const int*p)的函数
因为无法知道p
p
指向多少个int,所以您需要类似于
int max(const int*begin,const int*end)的内容和类似。@aschepler错误:“模板Iter算法::最大值(Iter,Iter)”的重新定义@ChrisHutchison,但它们确实存在干扰,因为它们具有相同的签名,有没有办法避免这种情况?
// C++17 void_t
template <typename...>
using void_t = void;

template <typename T, typename = void>
struct is_iterator : std::false_type {
};

template <typename T>
struct is_iterator<T, void_t<typename   std::iterator_traits<T>::iterator_category>> : std::true_type {
};

template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;

template<typename T, std::enable_if_t<!is_iterator_v<T>, int> = 0>
constexpr T maximum(T a, T b)
{
    return (a > b) ? a : b;
}

template<typename Iter, std::enable_if_t<is_iterator_v<Iter>, int> = 0>
constexpr Iter maximum(Iter begin, Iter end)
{
    if(begin == end) {
        return end;
    }
    auto max = begin;
    for (; begin != end; ++begin) {
        if(*begin > *max) {
            max = begin;
        }
    }
    return max;
}