1

1 つは特定のケースをキャッチし、もう 1 つは最初のケースと一致しない他のすべてのケースをキャッチするように、2 つのテンプレート関数を作成したいと考えています。std::enable_if を使用して特定のケースをキャッチしようとしていますが、コンパイラがあいまいな一致で失敗します。あいまいさがコンパイラによって解決されるように、これらのオーバーロードされた関数を作成するにはどうすればよいですか? (私はg ++を使用しています)

次のコードを書いてみました (これは問題を再現する簡単な例です)。

struct resource1_t{
};

struct resource2_t{
};

template <typename R, typename V>
struct unit_t{
  typedef R resource_t;
  typedef V value_t;
  unit_t(value_t const& value):v(){}
  value_t v;
  value_t calcValue(resource_t const& r)const{return v;}
};

// Specific case (U::resource_t == R)
template <typename U, typename R, typename=std::enable_if_t<std::is_same_v<typename U::resource_t,R>>>
      typename U::value_t callCalcValue(U const& u, R const& r){
        return u.calcValue(r);
      }

 // General case (U::resource_t != R)
 template <typename U, typename R>
      typename U::value_t callCalcValue(U const& u, R const& r){
        // Fail immediately!
        assert(!"Unit resource does not match");
        return U::value_t();
      }

int main()
{
    // Create an array of unit variants
   typedef unit_t<resource1_t,int> U1;
   typedef unit_t<resource2_t,float> U2;
   std::vector<std::variant<U1,U2>> units;
   units.emplace_back(U1(1));
   units.emplace_back(U2(1.0f));

   // Create a parallel array of resources
   std::vector<std::variant<resource1_t,resource2_t>> resources;
   resources.emplace_back(resource1_t());
   resources.emplace_back(resource2_t());

   // Call calcValue for each unit on the parallel resource
   for(int i(0); i<units.size(); ++i){
       std::visit([&](auto&& unit){
           std::visit([&](auto&& resource){
             // Fails to compile with substitution failure...
             //std::cout << unit.calcValue(resource) << "\n";

             // Results in ambiguous call compile error...
             std::cout << callCalcValue(unit,resource) << "\n";
           },resources[i]);
       },units[i]);
   }
}

私はコンパイラがすべてのケースを特定のケースに一致させ、他のすべての組み合わせを一般的なケースに一致させることを期待していましたstd::is_same_v<U::resource_t,R>が、コンパイラは関数があいまいであると言って失敗しました。2番目の定義も試し! std::is_sameましたが、コンパイラは失敗しますerror: redefinition of ... callCalcValue()...

4

2 に答える 2