2

最初の引数を 2 番目の引数の値に設定する関数を作成しようとしています。ただし、第2引数がコンテナクラスの場合、第1引数をコンテナの第1要素に設定したい。同様の問題に答えるこの質問を見つけましたが、私の場合はうまくいかないようです。

このコードをコンパイルすると、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

引数を省略記号に渡すと、関数のオーバーロードが同じ引数の実パラメーターを持つものよりも優先されなくなりますが、呼び出しに 3 番目の引数がないため、ここでは取り上げません。

私は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 に答える