6

関数を演算子に渡す必要があります。正しい arg 型を持つ任意の単項関数。戻り値の型は何でもかまいません。fこれはライブラリ コードであるため、ラップしたり、特定のオーバーロード (の外部) にキャストしたりすることはできませんoperator*。関数はoperator*、それ自身の引数として 1 番目の引数を取ります。以下の人為的な例は、コンパイルして正しい結果を返します。intただし、この例をコンパイルするために、戻り値の型がハードコーディングされています。

#include <tuple>
#include <iostream>
using namespace std;

template<typename T>
int operator* (T x,  int& (*f)(T&) ) {
    return (*f)(x);
};

int main() {
    tuple<int,int>  tpl(42,43);
    cout << tpl * get<0>;
}

任意の戻り値の型でoperator*受け入れるようにすることはできますか?f

更新 - GCC バグ? コード:

#include <tuple>

template<typename T, typename U> 
U operator* (T x,  U& (*f)(T&) ) {  
    return (*f)(x);
}; 

int main() {
    std::tuple<int,int>  tpl(42,43);
    return   tpl * std::get<0,int,int>;
}  

gcc462 および 453 では正しくコンパイルおよび実行されますが、gcc471 および 480 では拒否されます。したがって、GCC リグレッション バグの可能性があります。バグレポートを提出しました: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111

編集 タプルを引数として使用するように例を変更しました-前の例では戻り値の型を自明に推測できました。

EDIT2 多くの人が何が必要なのか理解できなかったので、例をより現実的にするためにcall機能を変更しました。operator*

4

3 に答える 3

4

はい、これがあなたの言いたいことなら:

template<typename T, typename F> 
auto call (T x, F f) -> decltype(f(x)) {  
    return (f)(x); 
}

それを行うには、実際には多くの方法があります。

于 2012-07-28T02:26:46.437 に答える
2

更新された質問への回答として:

@DavidRodríguezによって議論されたように、get<0>十分ではなく、構文的に正しいものでもありません&get<0>。必要なのはです&get<0,int,int>。あなたの例に従うと、それは次のようになります:

#include <tuple>
using namespace std;

template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
      return (*f)(x);
};

int main() {
    tuple<int,int>  tpl(42,43);
    call(tpl, &get<0,int,int>);
    return 0;
}

の通常の使用中std::get<>()int,intパーツは自動的に推定されます。しかし、あなたの状況では、パラメータがないので、それを提供する必要があります。1つの回避策は、カスタムgetテンプレート関数です。

#include <tuple>
using namespace std;

template <size_t I, typename T>
auto myGet(T& tpl) -> decltype(get<I>(tpl))
{
    return get<I>(tpl);
}

template<typename T, typename U>
U call (T x, U (*f)(T&) ) {
      return (*f)(x);
};


int main() {
    tuple<int,int>  tpl(42,43);
    auto get0 = &myGet<0, decltype(tpl)>;
    call(tpl, get0);

//  call(tpl, &myGet<0, decltype(tpl)>); // all in one line, do not work
    return 0;
}
于 2012-07-28T05:53:39.720 に答える
2

これを行うことができるはずです:

template<typename T,typename U>
U call (T x, U (*f)(T) ) {
      return (*f)(x);
};
于 2012-07-28T02:58:25.117 に答える