10

関数ポインター関数によってテンプレート化されたテンプレートパラメーターとして、キャプチャーなしのラムダを渡すことができないようです。私はそれを間違った方法でやっていますか、それとも不可能ですか?

#include <iostream>

// Function templated by function pointer
template< void(*F)(int) >
void fun( int i )
{
    F(i);
}

void f1( int i )
{
    std::cout << i << std::endl;
}

int main()
{
    void(*f2)( int ) = []( int i ) { std::cout << i << std::endl; };

    fun<f1>( 42 ); // THIS WORKS
    f2( 42 );      // THIS WORKS
    fun<f2>( 42 ); // THIS DOES NOT WORK (COMPILE-TIME ERROR) !!!

    return 0;
}
4

2 に答える 2

11

これは主に言語の定義の問題であり、次のようにするとより明白になります。

using F2 = void(*)( int );

// this works:
constexpr F2 f2 = f1;

// this does not:
constexpr F2 f2 = []( int i ) { std::cout << i << std::endl; };

実際の例

これは基本的に、あなたの希望/期待が非常に合理的であることを意味しますが、言語は現在そのように定義されていません-ラムダは、として適切な関数ポインターを生成しませんconstexpr.

ただし、この問題を修正するための提案があります: N4487

于 2015-06-24T16:45:10.863 に答える
4

これは実行可能でf2はありませんconstexpr(つまり、ランタイム変数ではないため)。そのため、テンプレート パラメーターとして使用することはできません。次の方法でコードを変更し、より汎用的にすることができます。

#include <iostream>

template<typename F, typename ...Args>
void fun(F f, Args... args) {
  f(args...);
}

void f1( int i ) {
    std::cout << i << std::endl;
}

int main() {
    auto f2 = []( int i ) { std::cout << i << std::endl; };
    fun(f1, 42);
    f2( 42 );
    fun(f2, 42 );
    return 0;
}
于 2015-06-24T16:37:57.983 に答える