2

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

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

2 回答 2

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;
}

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

于 2012-08-12T02:43:37.677 回答
-1

函数模板不能做特化。这就是为什么

于 2012-08-12T02:33:56.980 回答