2016-11-19 2 views
4

関数の引数に与えられた型のを持つラムダを取るクラスメンバ関数を書いています。私の質問です:議論の変更可能性に基づいてコンパイル時にメンバー関数をオーバーロードすることは可能ですか?以下は例です:可変/不変ラムダのコンパイル時のスイッチ

// T is a given type for class. 
template <typename T> 
class Wrapper { 

    T _t;  

    // For T& 
    template <typename F, typename R = std::result_of_t<F(T&)>> 
    std::enable_if_t<std::is_same<R, void>::value> operator()(F&& f) { 
    f(_t); 
    } 

    // For const T& 
    template <typename F, typename R = std::result_of_t<F(const T&)>> 
    std::enable_if_t<std::is_same<R, void>::value> operator()(F&& f) const { 
    f(_t); 
    } 
}; 

だから、私が欲しいのは所与のラムダは、次の署名がある場合、最初のオペレータが呼び出されるべきです。

定数引数の場合は、2番目の引数を呼び出す必要があります。

[](const T&) { 
} 

答えて

1

あなたは唯一の非キャプチャラムダを使用することを計画している場合、あなたは彼らが関数へのポインタに減衰するという事実に依存することができます。それは次のようにそうしないと、2つのオーバーロード関数を使用することができます

#include<type_traits> 
#include<iostream> 

template <typename T> 
class Wrapper { 
    T _t;  

public: 
    auto operator()(void(*f)(T &)) { 
     std::cout << "T &" << std::endl; 
     return f(_t); 
    } 

    auto operator()(void(*f)(const T &)) const { 
     std::cout << "const T &" << std::endl; 
     return f(_t); 
    } 
}; 

int main() { 
    Wrapper<int> w; 
    w([](int &){}); 
    w([](const int &){}); 
} 

#include<type_traits> 
#include<iostream> 
#include<utility> 

template <typename T> 
class Wrapper { 
    T _t;  

    template<typename F> 
    auto operator()(int, F &&f) 
    -> decltype(std::forward<F>(f)(const_cast<const T &>(_t))) const { 
     std::cout << "const T &" << std::endl; 
     return std::forward<F>(f)(_t); 
    } 

    template<typename F> 
    auto operator()(char, F &&f) { 
     std::cout << "T &" << std::endl; 
     return std::forward<F>(f)(_t); 
    } 

public: 
    template<typename F> 
    auto operator()(F &&f) { 
     return (*this)(0, std::forward<F>(f)); 
    } 
}; 

int main() { 
    Wrapper<int> w; 
    w([](int &){}); 
    w([](const int &){}); 
} 
+0

うーんを
それは、最小限、実施例に従います。これは良いようです。しかし、どのように私は与えられたラムダからの戻り値の型でこの操作をオーバーロードするのですか?与えられたfはvoidだけでなく、独自の戻り値型を持つことができます。 – Jes

+0

@Jesが更新されました。戻り値の型が導出されるようになりました。 – skypjack

+0

ありがとう!それを消化させてください。 – Jes