1

関数名を受け取り、いくつかのアクションを実行するいくつかのマクロを作成しています。そのうちの 1 つは署名を取得し、decltypeそれをテンプレート パラメーターとして使用します。

これらのマクロを拡張して、オーバーロードされた関数をサポートしたいと考えています。私の考えは、引数リストを指定する追加の引数を取らせることですが、完全な署名ではありません. オーバーロードされていない場合に行ったように、関数の完全なシグネチャを再構築しようとすると、問題が発生しdecltypeます。戻り値の型を推測するにはどうすればよいですか?

で試しましresult_ofたが、運がありません:

#include <type_traits>
#include <typeinfo>
#include <iostream>
using namespace std;

double f(int, int);
int f(int, int, int);

int main(){
    cout<<typeid(result_of<decltype(&f)(int,int, int)>::type).name()<<endl;
}

double f(int, int)コメントアウトされている場合、スニペットは機能します。decltypeこれは、2 つのオーバーロードのどちらを選択するかが不明なためであると理解しています。通常、目的のオーバーロードに一致する署名の前にダミー キャストを追加しますが、それは戻り値の型を事前に知っていることを意味するため、これらすべてが役に立たなくなります。

この問題を解決する方法はありますか? または、マクロで完全な署名を指定するようにユーザーに強制する必要がありますか?

編集:基本的に、私はこれらの2つのマクロを持っています:

//add a member function as a method
#define addmethod2(stringname, methodname)      fields[#stringname]=method_helper<decltype(&hold_type::methodname), &hold_type::methodname>::worker
#define addmethod(methodname)                   addmethod2(methodname, methodname)

正しいメンバー関数のオーバーロードを選択するために、引数リストのみaddmethod3を受け取る3 番目の を追加します (戻り値の型を持つ完全なシグネチャである場合は簡単です)。

4

2 に答える 2

2

どうですか

template<typename T>
struct identity { typedef T type; };

template<typename T>
using NoDeduce = typename identity<T>::type;

template<typename T>
using Identity = T;

template<typename ...P, typename R>
Identity<R(P...)> *get_f(R f(NoDeduce<P>...)) {
  return f;
}

それからあなたは言うことができます

auto *f1 = get_f<int, int, int>(f);
auto *f2 = get_f<int, int>(f);
于 2012-05-01T13:26:42.573 に答える
1

decltype呼び出し式を使用して作成します: decltype(f(0, 0, 0)). int引数が ( とは異なり)のインスタンスを簡単に提供できない型である場合は、std::declvalそれを偽造するために使用します。

decltype(f(std::declval<int>(), std::declval<int>(), std::declval<int>()))
于 2012-04-29T22:24:26.877 に答える