2016-09-20 16 views
-1

これは this SO questionの変形です。オーバーロードされた関数のランタイム特化

struct mystruct { 
    auto f (int x, int y) -> int; 
    auto f (std::string x, int y) -> float; 
}; 

そのパラメータの一つ回数を専門に自身を呼び出す必要がf機能:私は、異なる種類のパラメータを取り、様々なタイプを返すオーバーロードされた機能を持っています。 パラメータyを特化した関数を定義したいと思います。つまり、g(z) = f(z,y)が必要です。戻り値の型はgであり、固有のパラメータの型はzですが、どちらの場合も実装は同じです。期待通りに動作しますが、やり過ぎのようだ

template <class F1, class F2> 
struct overload_set : F1, F2 
{ 
    overload_set(F1 f1, F2 f2) : F1(f1), F2(f2) {} 

    using F1::operator(); 
    using F2::operator(); 
}; 
template <class F1, class F2> 
overload_set<F1, F2> overload(F1 f1, F2 f2) { 
    return overload_set<F1, F2>(f1, f2); 
}; 

struct mystruct { 
    auto f(std::string x, int y) -> float { 
    return y+9.3; 
    } 
    auto f(int x, int y) -> int 
    { 
    auto g = overload (
     [=](int z) -> int {return f(z,y);}, 
     [=](std::string z) -> float { return f(z,y); } 
    ); 
    if (x == 0) { 
    std::cout << g("this string") << "\n"; 
    return 0; 
    } 
    if (x == 1) return y; 
    return 7; 
    } 
}; 
int main() { 
    mystruct h; 
    std::cout << h.f(1,4) << "\n"; 
    std::cout << h.f(0,2) << "\n"; 
} 

:私はこのような状況で見つけることができる

最高の実装では、ラムダ関数をオーバーロードされます。

#define k(z) f(z,y) 

のような単純なプリプロセッサマクロも動作するようです。これを達成する良い方法はありますか?

+0

あなたはC++ 11に制限されていますか?単純に 'auto g(auto z) - > decltype(f(z、y))'を使うのはなぜですか? –

+0

私はそれを試して、うまくいきませんでした。答えとしてそのアプローチで動作するコードを投稿すれば、私はそれを受け入れていただきありがとうございます。 –

+0

'y'はどこから来たのですか? – Barry

答えて

1

これは作業が何であるか、あなたがここで行うが、しようとしている(C++ 14)の例であればわからない:

#include <iostream> 

struct mystruct { 
    static auto f (int x, int y) -> int { 
    std::cout << "f(" << x << "," << y << ")" << std::endl; 
    auto g = [=](auto z) -> decltype(mystruct::f(z, y)) { 
     return mystruct::f(z, y); 
    }; 
    if (x < 1) 
     g("end"); 
    else 
     g(x - 1); 
    } 
    static auto f (std::string x, int y) -> float { 
    std::cout << "f(\"" << x << "\"," << y << ")" << std::endl; 
    } 
}; 

int main() { 
    mystruct::f(10, 1); 
} 

出力:

f(10,1) 
f(9,1) 
f(8,1) 
f(7,1) 
f(6,1) 
f(5,1) 
f(4,1) 
f(3,1) 
f(2,1) 
f(1,1) 
f(0,1) 
f("end",1) 
+0

ああ申し訳ありませんが、私は私の元の質問に投稿しましたが、この例ではなく、 'g'は私の例のように' f'の中で呼び出されます。私は質問 –

+0

を編集します。それは再帰のようなものです(?)私はこれがロジックの中で何か変わるとは思わない...あなたがいつ過負荷の1つを呼び出すか、別のものを呼び出すかはわかりません。 ..ランタイムパラメータ値に依存していますか? –

+0

はい、関数 'g'は、パラメータの束が同じで、ただ1つのパラメータを変更するだけでfを呼び出すためのラッパーでなければなりません。質問の私の例では、これは動作しますが、少し複雑です。私はあなたの例をこのようにする方法を知らない。 –

0

アムI何かが欠けている?

これは、同じ答えを生成し、私は少し明確だと思う:

#include <string> 
#include <iostream> 

struct mystruct 
{ 
    auto f(std::string x, int y) -> float { 
     return y+9.3; 
    } 

    auto f(int x, int y) -> int 
    { 
     switch(x) 
     { 
      case 0: { 
       auto g = [=](auto...args) { return f(args..., y); }; 
       std::cout << g("this string") << "\n"; 
       return 0; 
      } break; 

      case 1: { 
       return y; 
      } break; 

      default: 
       return 7; 
     } 
    } 
}; 
int main() { 
    mystruct h; 
    std::cout << h.f(1,4) << "\n"; 
    std::cout << h.f(0,2) << "\n"; 
} 

はたぶん現実には複数のスイッチ場合がある、とgswitch文の上に掲揚する必要がありますか?

関連する問題