2016-05-16 4 views
1

を返す私は、戻り値の型のオーバーロードのための構造体を使用してのトリックを知っている:は、パラメータの両方の機能をオーバーロードし、種類

struct function { 
    operator typeA() { return overloadForTypeA(); } 
    operator typeB() { return overloadForTypeB(); } 
} 

問題は、このパラメータとパラメータの型のオーバーロードを無効にしていることです。だから私はテンプレートを使用してこの概念を拡張しようとしてきた:

struct function { 
    //template on the constructor so types are inffered from arguments 
    template<typename... Args> 
    funct(Args... arguments) { myArguments = arguments; } 

    //intermediate storeage of arguments, problem is the template doesn't extend to here 
    Args myArguments; 

    //overloads for return type int 
    int overloadForInt(char* chr) { return 20; } 
    int overloadForInt(int i) { return 4; } 

    //overloads for return type char 
    char overloadForChar(char* chr) { return 'c'; } 
    char overloadForChar(int i) { return 'i'; } 

    //implcit cast operators to archive return type overloading 
    operator int() { return overloadForInt(myArguments...); } //if myArguments doesn't match any overload of overloadForInt compile error should happen 
    operator char() { return overloadForChar(myArguments...); } 
} 

ご覧のように、私はstuctの残りの部分まで延びていないテンプレートの問題に遭遇しました。この特定の問題を解決するために構造体全体にわたってコンストラクタテンプレートを拡張する方法はありますか?または、パラメータとパラメータ型のオーバーロードを維持しながら、戻り型をオーバーラップ可能にする別の方法がありますか?

+2

「無効なパラメータとパラメータのタイプのオーバーロード」という意味をもう少し説明してください。 – linuxfever

+0

クラスそのものを 'Args ...'(または任意の名前)をとるテンプレートにします。 – 0x499602D2

+0

"パラメータを無効にする..."とは、暗黙のキャストは何も取らないので、引数を渡すことはできません。また、私は構造体そのものをテンプレートにすることはできません。なぜなら、引数の型はコンストラクタから入力されないので、 "function(parameters)"の代わりに "function (parameters)"です。 。これは、通常の機能と同じ構文を持つという目的を破るものです。 (その後、ダミーポインタを使用するほうがよいでしょう) –

答えて

1

暗黙的なキャスト演算子は、overloadForXXXを引数以上で呼び出す可能性があり、コンパイルエラーが発生する可能性があります。以下では、コンストラクタで渡す各引数を使ってオーバーロードを呼び出すことに興味があるという前提を立てます。 Boost Fusionライブラリの使用に注意してください。その考え方は、関数クラスをクラステンプレートにしてからヘルパー関数を使用して、そのクラスを作成して、あなたのために引数の型を推論することです。

#include <boost/fusion/adapted/std_tuple.hpp> 
#include <boost/fusion/include/for_each.hpp> 
#include <iostream> 



template <class... Args> 
class function { 

    // using a tuple to store the arguments 
    std::tuple<Args...> m_args; 

public: 
    function(Args... args) 
: m_args(std::forward<Args>(args)...){} 

private: 
    struct call_for_int { 

    void overload(char* chr) { 
     std::cout << "Called Int overload with char" << std::endl; 
    } 

    void overload(int chr) { 
     std::cout << "Called Int overload with int" << std::endl; 
    } 

    template <class T> 
    void operator()(T&& t) { 
     overload(std::forward<T>(t)); 
    } 
    }; 

    struct call_for_char { 

    void overload(char* chr) { 
     std::cout << "Called Char overload with char" << std::endl; 
    } 

    void overload(int chr) { 
     std::cout << "Called Char overload with int" << std::endl; 
    } 

    template <class T> 
    void operator()(T&& t) { 
     overload(std::forward<T>(t)); 
    } 
    }; 

public: 
    // use this to call the char overloads 
    void call_char() { 
    auto fun = call_for_char(); 
    boost::fusion::for_each(m_args, std::ref(fun)); 
    } 

    // use this to call the int overloads 
    void call_int() { 
    auto fun = call_for_int(); 
    boost::fusion::for_each(m_args, std::ref(fun)); 
    } 
}; 

// helper function to infer the passed arguments 
template <class... Args> 
auto make_function(Args&&... args) { 
    return function<Args...>(std::forward<Args>(args)...); 
} 

int main() { 
    auto f = make_function(4, 2, 42); 
    f.call_char(); 
    f.call_int(); 
} 
+0

ありがとう!私は引数を入力するためのヘルパ関数の考え方を考え出すことはありません。 –

+0

うれしい私は助けることができました! – linuxfever

関連する問題