2016-05-05 28 views
2

std::crefを使用しているときにこの問題が発生しました。最小限の例では、次のようになります。オーバーロードされた関数テンプレートのインスタンス化

template<typename Fn, typename T> 
auto apply(Fn f, const T &t) -> decltype(f(t)) 
{ 
    return f(t); 
} 

int n = 123; 
apply(std::cref<int>, n); // <- compile error: can't infer type `Fn` 
apply([](const int &x) { return std::cref(x); }, n); // ok 

は、私が最初の例に問題がstd::cref<T>は、2つのオーバーロードされたバージョン、1はconst T &を受け入れ、他のstd::reference_wrapper<const T>を受け入れるを持っているということだと思います。私の場合、特定のバージョンをインスタンス化することは可能ですか?

+1

'適用されます(static_castを<はstd :: reference_wrapper (*)(のconst int型&)を>(&はstd :: CREF )、N);'が、ラムダが悪いのでしょうか? –

+0

@PiotrSkotnicki 'std :: vector 'を 'std :: vector >'に変換するために 'fmap(std :: cref、foos)'のような処理をしようとしていましたが、文法はより洗練されたものになります。しかし、それはおそらく不可能です! –

+0

あなた自身の参照ラップ関数を追加し、 'fmap(mycref、foos)'を持つことができます –

答えて

1

crefにはいくつかの形式があります。ですから、cref<int>を書くとき、あなたが意味以下のどのまだ明らかではない。

reference_wrapper<const int> cref (const int& elem) 
reference_wrapper<const int> cref (reference_wrapper<int>& x) 

ラムダバージョンは、この曖昧さを持っていません。

auto take_ref = [](const int &x) { return std::cref(x); }; 
apply(take_ref, n); // compile fine 
2

あなたapply機能は一種の冗長ようだ:ところで、それは今、可読性が本当に問題であるならば、何もこれを実行できないようにしない、それ;-)

に慣れるすることをお勧めしますこの場合。なぜ仲介者を切らないのですか?

#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <functional> 

int main() { 
    std::vector<int> v(10); 
    std::vector<std::reference_wrapper<const int>> v2; 
    std::transform(v.begin(), v.end(), std::back_inserter(v2), 
     static_cast<std::reference_wrapper<const int>(*)(const int&)>(&std::cref<int>)); 
} 
+0

実際のコードを単純化するために 'apply'関数が考案されました。実際の状況では、実際には 'std :: transform'に似たものです。 –

関連する問題