可变类的C ++函数重载

时间:2012-08-12 02:19:49

标签: c++ templates overloading

我正在尝试编写一个函数,将第一个参数设置为第二个参数的值。但是,当第二个参数是容器类时,我希望它将第一个参数设置为容器的第一个元素。我发现this问题可以解决类似的问题,但是,我似乎无法在我的案例中使用它。

当我编译这段代码时,我得到一个错误,说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;
}

2 个答案:

答案 0 :(得分:2)

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

我会同时使用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;
}

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

答案 1 :(得分:-1)

功能模板不能做专业化。 this is why