2016-05-07 5 views
3

だから、私は、アルゴリズムに一度それらを使用できるように、「順次」、ボイドラムダを構成する機能を書いた:関数テンプレートは、ローカルラムダで動作しますが、いない他の機能との

template <typename F, typename... Fs> 
auto lambdaList(F f, Fs... fs) 
{ 
    return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); }; 
} 

template <typename F> 
auto lambdaList(F f) 
{ 
    return [=] (auto&... args) { f(args...); }; 
} 

私ならばそれは動作します地元のラムダを使用しますが、私は別の名前空間に関数を使用しないとき:

main.cpp:11:56: note: candidate expects at least 1 argument, 0 provided 
    return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); }; 
               ~~~~~~~~~~^~~~~~~ 

#include <iostream> 

namespace foo { 
    void a() { std::cout << "a\n"; } 
    void b() { std::cout << "b\n"; } 
} 

template <typename F, typename... Fs> 
auto lambdaList(F f, Fs... fs) 
{ 
    return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); }; 
} 

template <typename F> 
auto lambdaList(F f) 
{ 
    return [=] (auto&... args) { f(args...); }; 
} 

int main() { 
    auto printStarBefore = [] (const std::string& str) { 
     std::cout << "* " + str; 
    }; 
    auto printStarAfter = [] (const std::string& str) { 
     std::cout << str + " *" << std::endl; 
    };  

    lambdaList(printStarBefore, printStarAfter)("hi"); // ok 
    lambdaList(foo::a, foo::b)();      // error 
} 

エラーがno matching function for call to 'lambdaList()'であります

なぜ時々動作するのですか?

+0

私はあなたの例を完全に自己完結型に編集しました。将来、良い質問のガイドラインは[mcve]を提供することです。 – Barry

答えて

6
あなたの機能を反転させる必要がある

:AS-IS

template <typename F> 
auto lambdaList(F f) 
{ 
    return [=] (auto&... args) { f(args...); }; 
} 

template <typename F, typename... Fs> 
auto lambdaList(F f, Fs... fs) 
{ 
    return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); }; 
} 

、あなたのベースケースは、あなたの再帰的な場合には修飾されていない検索によって発見されることはありません - それは唯一の引数依存の検索で見つけることができます。引数がlambdaListと同じ名前空間にない場合、引数はまったく見つからず、再帰的なステップは常にそれ自身を呼び出します。それがあなたのエラーの原因です。

新しい注文では、ベースケースlambdaList()が通常の正規化されていない参照によって見つかることができます。これは再帰的なlambdaList()の定義時点で表示されます。


私たちはもっとうまくいくと言いました。すべてを呼び出す1つの関数を書く:

template <typename... Fs> 
auto lambdaList(Fs... fs) { 
    using swallow = int []; 
    return [=](auto const&... args) { 
     (void)swallow{0, 
      (void(fs(args...)), 0)... 
     }; 
    }; 
} 

これで、どのようなルックアップについても心配する必要はありません。実に分かりやすいです

template <typename... Fs> 
auto lambdaList(Fs... fs) { 
    return [=](auto const&... args) { 
     (fs(args...), ...); 
    }; 
} 

:あなたは、いくつかのC++ 1Z機能をサポートしています。現代の十分なコンパイラへのアクセス権を持っている場合は、上記大幅に削減することができます!

+0

"そのまま、再帰的なケースではルックアップによってベースケースが見つからないでしょう - それは常に自分自身を呼び出すでしょう。" [要出典](http://ideone.com/aO86oA)。 –

+0

@ n.m。問題の新しい例を試してみてください。 – Barry

+0

ありがとう、ありがとう。 –

関連する問題