C++可迭代类的函数重载

C++ Function Overloading For Iterable Classes

本文关键字:函数 重载 迭代 C++      更新时间:2023-10-16

我正在尝试编写一个函数,将第一个参数设置为第二个参数的值。但是,当第二个参数是容器类时,我希望它将第一个参数设置为容器的第一个元素。我发现了这个问题,它回答了一个类似的问题,但是,我似乎无法让它在我的情况下起作用。

当我编译此代码时,我收到一个错误,指出 SetVar 不明确。有没有办法让功能正常工作?

这是我到目前为止的代码...

#include <iostream>
#include <vector>
template<typename T1,typename T2>
static void SetVar(T1& a, const T2 &b, typename  T2::const_iterator= T2().begin()){
    //Check to make sure b contains an element.
    if(b.begin()!=b.end())  a=*b.begin();
}
template<typename T1,typename T2>
static void SetVar(T1& a, const T2 &b,...){
    a=b;
}
int main(int argc, const char * argv[])
{
    int x;
    int y=5;
    std::vector<int> z;
    z.push_back(1);
    z.push_back(3);
    SetVar(x, y);
    //Should print 5
    std::cout<<x<<"n";
    SetVar(x, z);//<---SetVar is ambiguous
    //Should print 1
    std::cout<<x<<"n";
    return 0;
}

将参数传递给省略号确实会使函数重载不如具有相同参数的实际参数的函数重载,但这不会出现在这里,因为您的调用中没有第三个参数。

我会将enable_if用于两者:

#include <type_traits>
// Enabled if T2 has `const_iterator` and `begin()`:
template<typename T1,typename T2>
auto SetVar(T1& a, const T2 &b)
  -> typename std::enable_if<std::is_convertible<
         decltype(std::declval<const T2&>().begin()),
         typename T2::const_iterator>::value
     >::type
{
    //Check to make sure b contains an element.
    if(b.begin()!=b.end())  a=*b.begin();
}
// Enabled if expression 'a=b' is valid.
template<typename T1,typename T2>
auto SetVar(T1& a, const T2 &b)
  -> typename std::enable_if<std::is_assignable<T1, const T2&>::value>::type
{
    a=b;
}

上述内容仍有可能模棱两可,但前提是两个条件都为真,这意味着正在进行奇怪的容器或隐式转换 - 在这种情况下,我希望编译器警告我混淆。

函数模板不能做专用化。

这就是为什么