26

私は頭の中で十分に単純なアイデアに頭を悩ませていますが、C++で実装する方法がわかりません。

通常、次の簡単な例のように、変換演算子を使用してクラスを宣言できます。

class Foo
{
private:

    int _i;

public:

    Foo( int i ) : _i(i) { }

    operator int( ) const
    {
        return i;
    }
};

だから今、私は次のような素晴らしいものを書くことができます

int i = Foo(3);

しかし、私の特定のケースでは、オブジェクトを関数ポインターに変換するための演算子を提供したいと思います(たとえば、Barインスタンスをint(*)(int, int)関数ポインターに変換する)。これが私が最初に試したことです:

class Bar
{
private:

    int (*_funcPtr)(int, int);

public:

    Bar( int (*funcPtr)(int, int) ) : _funcPtr(funcPtr) { }

    operator int(*)(int, int) ( ) const
    {
        return _funcPtr;
    }

};

しかし、演算子関数はコンパイルに失敗し、次のエラーが生成されます。

expected identifier before '*' token
'<invalid-operator>' declared as a function returning a function

リターンタイプを括弧で囲むなど、上記の簡単なバリエーションも試しましたが、これらのアイデアもすべて失敗しました。

関数ポインターへの変換演算子メソッドを宣言するための構文が何であるか、またはそれが可能であるかどうかを誰かが知っていますか?

注:GCC4.5.2を使用してCode::Blocksでこれをコンパイルしています。新しいC++0xの概念のいくつかに関する回答も歓迎します。

編集

例を単純化するための努力の中で、私は意図せずに1つの詳細を省略しました。少し奇妙ですが、厳密にポインタを返すのではなくint(*)(int,int)、変換演算子はテンプレート化することを目的としています。

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
    // implementation is unimportant here
}

私の知る限り、そのような型をtypedefすることはできなくなりました。これは明らかに物事をはるかに不器用にしますが、まだ方法があることを願っています。

4

6 に答える 6

19

あなたが知っている必要があるので:

(*operator int() const)(int, int)
{
  return _funcPtr;
}

(修正されました。もう一度。)


更新: JohannesSchraubとLucDantonから、この構文は実際には無効であり、実際にはtypedefを使用する必要があると通知されました。typedefはオプションではないと言っているので、typedefをラップできるヘルパークラスを次に示します。

template<typename R, typename A1, typename A2>
struct MakeFunctionType
{
  typedef R(*type)(A1, A2);
};

template<typename R, typename A1, typename A2>
operator typename MakeFunctionType<R, A1, A2>::type () const
{
    // implementation is unimportant here
}
于 2011-07-20T00:36:46.327 に答える
4

typedefを使用します。とにかく、読みやすいです:

class Bar
{
public:
  typedef int (*fptr_t)(int, int);

  Bar(fptr_t funcPtr) : _funcPtr(funcPtr) { }

  operator fptr_t() const
  {
    return _funcPtr;
  }

private:
  fptr_t _funcPtr;
};

[編集]

テンプレートの場合、typedefの使用方法がわかりません。@Kerrikは、機能するはずの構文の(乱雑な)バージョンを提供します。

于 2011-07-20T00:25:14.573 に答える
1

編集:

クラスには、構築時に割り当てられた非テンプレート関数ポインタがあるため、次のようになります。

private:

    int (*_funcPtr)(int, int);

後でそれを任意のタイプの関数ポインタに変換することはまったく不可能です。

したがって、クラステンプレートメンバー演算子のオーバーロードではなく、テンプレートクラスメンバー演算子のオーバーロードを意味していると想定します。

テンプレートバージョン:

template<typename ReturnType, typename ArgType1, typename ArgType2>
class Bar {

public:

  typedef ReturnType (*fptr_t)(ArgType1, ArgType2);

  operator fptr_t ( ArgType1 arg1, ArgType2 arg2 ) const
  {
      // implementation is unimportant here
  }

//etc...

};

次に、次のように使用します。

//create functor to some function called myfunc
Bar::fptr_t func_ptr = Bar<int, int, int>(&myfunc); 

//call functor
int i = func_ptr(1,2); 
于 2011-07-20T00:39:43.417 に答える
1

コードを読みやすくしたい場合は、typedef を使用する必要があります。関数ポインタを型定義せずに使用することすらありません。構文があまりにも恐ろしいです。

ゴール:

template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
   return 0;
}

道:

// 1: helper structure
template <typename R, typename A0, typename A1>
struct helper {
  typedef R (*type)(A0,A1);
};

// 2: operator
template <typename R, typename A0, typename A1>
operator typename helper<R, A0, A1>::type() const {
  return 0;
}

イデオンでチェック!

于 2011-07-20T06:56:29.490 に答える