16

組み込み演算子の関数ポインタを参照したいのですが、具体的な型オーバーロードの指定方法がわかりません。

次のテンプレート クラス シグネチャがあります。

template<typename ParamsType, typename FnCompareType>
class MyAction
{
public:
    MyAction(ParamsType& arg0, ParamsType& arg1, FnCompareType& fnCpmpare) 
    : arg0_(arg0), arg1_(arg1), fnCompare_(fnCpmpare) {}

    bool operator()()
    {
        if((*fnCompare_)(arg0_,arg1_)
        {
            // do this
        }
        else
        {
            // do s.th. else
        }
    }

private:
    ParamsType& arg0_;
    ParamsType& arg1_;
    FnCompareType& fnCompare_;
}

そして、次のような構文を使用したい:

void doConditional(int param1, int param2)
{
    MyAction<int,&::operator>=> action(param1,param2);
    if(action())
    {
        // Do this
    }
    else
    {
        // Do that
    }
}

しかし、それはコンパイルされません:

error: ‘::operator>=’ has not been declared

このような固有の静的操作を参照するにはどうすればよいですか?

4

2 に答える 2

22

組み込み演算子

それらの関数ポインターを持つことができない理由:

C++11、§13.6/1、[over.built]

箇条 5 で定義された組み込み演算子を表す候補演算子関数は、この節で指定されます。これらの候補関数は、13.3.1.2 で説明されているように、演算子のオーバーロード解決プロセスに参加し、他の目的には使用されません

組み込み演算子(組み込み型の演算子) は、実際の演算子関数ではありません。したがって、それらを指す関数ポインターを持つことはできません。operator<(A,B)また、構文を使用して呼び出すこともできません。それらはオーバーロードの解決にのみ参加しますが、コンパイラはそれらを適切な asm/machine 命令に直接変換し、「関数呼び出し」は一切行いません。

この問題を回避する方法:

user1034749 はすでにこの質問に回答していますが、完全を期すために:

標準では、 §20.8 の [function.objects]で多くの関数オブジェクトを定義しています。

  • 算術演算
  • 比較
  • 論理演算
  • ビット演算

関数オブジェクトは、関数オブジェクト型のオブジェクトです。関数へのポインターをアルゴリズム テンプレートに渡すことが期待される場所 (第 25 節) では、関数オブジェクトを受け入れるようにインターフェイスが指定されます。これにより、アルゴリズム テンプレートが関数へのポインターを操作できるようになるだけでなく、任意の関数オブジェクトを操作できるようになります。

C++11、§20.8.5、[比較]

  • に等しい
  • not_equal_to
  • 大きく、小さく
  • より大きい_等しい
  • less_equal

これらはテンプレート化された関数オブジェクトであり、関数内で類似の演算子に減衰しoperator()ます。これらは、関数ポインターの引数として使用できます。

user1034749は正しいです、私は言いたいです:他に方法はありません.これらは「生の」関数ポインタと完全に同等です. 参考にした。

標準クラス型演算子

標準ライブラリ演算子を関数ポインタ (「実際の関数」として存在する) として使用できます。

ただし、テンプレートのそれぞれのインスタンスを参照する必要があります。コンパイラは、適切なテンプレートを推測するために適切なヒントを必要とします。

これは、を使用してMSVC 2012で機能しoperator+ますstd::basic_string

template<class Test>
Test test_function (Test const &a, Test const &b, Test (*FPtr)(Test const &, Test const &))
{
   return FPtr(a, b);
}

int main(int argc, char* argv[])
{
   typedef std::char_traits<char> traits_t;
   typedef std::allocator<char> alloc_t;
   std::basic_string<char, traits_t, alloc_t> a("test"), b("test2");
   std::cout << test_function<std::basic_string<char, traits_t, alloc_t>>(a, b, &std::operator+) << std::endl;
   return 0;
}

のテンプレート引数test_functionが推定されない場合、これは失敗します (少なくとも MSVC 2012 の場合)。

于 2013-07-15T01:36:45.043 に答える
9

C++ 標準ライブラリで使用されているものと同じソリューションを使用できます。

std::sort (numbers, numbers+5, std::greater<int>());

どこが大きいか

template <class T> struct greater : binary_function <T,T,bool> {
    bool operator() (const T& x, const T& y) const {return x>y;}
};

あなたの場合http://www.cplusplus.com/reference/functional/greater_equal/

ビルドされた演算子の参照について。

任意のクラスの既存の operator< を参照できます (もちろん、それらが非公開、保護されていない場合、またはクラス/関数がフレンドでない場合)。ただし、組み込み型 (bool、short、int、double) の opeator< は参照できません。上記の私のテキストからわかるように、C++標準を見ていない場合のイベント。

于 2013-07-14T23:49:02.737 に答える