12

public メソッドが 1 つしかない単純なクラスの API について、同僚と話し合っています。私は最初に行きました:

class CalculateSomething
{
public:
  void operator()(const SomeObject &obj) const;

private:
  // ...
}

しかし、私の同僚は operator() の使用に反対しており、わかりやすくするために単にメソッドに「calculate」という名前を付けたいと考えています。その議論に説得力があるとは思いませんが、賛否両論を考えさせられました。

利点 operator()

  • このクラスは無駄がなく、明確に定義された目的が 1 つあります。インスタンス化されると、基本的に無料の関数として機能します。
  • これはファンクターであり、そのまま簡単に使用できます (例: STL アルゴリズム)。
  • 範囲アルゴリズムで使用する場合、関数ポインターを介する代わりにオブジェクトを直接渡すことができます。これにより、コンパイラーはコードをインライン化できます。保証されていませんが、関数ポインターを介して渡すと、この可能性が完全に抑制されます。

デメリット operator()

  • クラス名を見ないと、メソッドが何をするかはあまり明確ではありません。(クラスにはメソッドが1つしかないため、その意味はクラス名から明らかであるため、個人的には同意しません)
  • STL のほとんどのファンクタは、ステートレスであると想定されています。これが私を引き留めている主な理由だと思います...

これは非常に一般的なシナリオ (1 つのクラス、1 つの責任) であると想定していたため、これに関する私の検索ではあまり出てこなかったことに驚きました。そういうわけで、私は他の人がこれについてどう思うかを聞くことに本当に興味があります.

4

2 に答える 2

3

ラムダが本当にオプションではない場合、選択はオブジェクトが行う作業の範囲に依存する必要があります...そして、コーディング規則やスタイルが原因です。明示的であることを決定できます ( Werolikの回答を参照)。メソッドが比較的なじみがなく、状態が必要な場合は良いことですが、

標準ライブラリから簡単なユースケースを取り上げてみましょう...

  • std::hash : これは 1 つのジョブを実行する関数オブジェクトであり、おそらくうまく機能します。
  • 他にもたくさん... std::less、およびその品揃えを含む

これらすべてに共通して見られることの 1 つは、それらが動詞であることです。私の見解では、クラスが投稿したスニペットとまったく同じであれば、CalculateSomethingはアクションを意味するので、いつでも としてインスタンス化できますCalculateSomething()(my_object...)

そして、あなたが引用したように、STLアルゴリズム自体や他の多くのC++ライブラリを使用するのに非常に便利です. 同僚の方法に行く場合は、インターフェイスを「適応」させたいため、std::binds とラムダを使用する必要がある場合があります。

例:

class CalculateSomething
{
    public:
         void operator()(const SomeObject &obj) const;
    private:
         // ...
}

class CalculateNothing
{
    public:
         void calculate(const SomeObject &obj) const;
    private:
         // ...
}

使用例は次のとおりです。

std::for_each(container.begin(), container.end(), CalculateSomething());

に対して

std::for_each(container.begin(), container.end(), [ c = CalculateNothing()](auto x) { c.calculate(x); });

私は前者の方が好きだと思います。

于 2016-02-09T10:28:26.537 に答える
1

さて、ここにも私の 5 セントがあります。

まず、可能であれば、ラムダ関数または無料関数を使用します。ニーズに合ったクラスが必要ですか?

とにかく、クラスが必要であると仮定します。

  1. operator() の使用はあまり好きではありません。たぶん、追加のコメントがあります。
  2. 名前を ' ' に変更した方がよいSomethingCalculatorのではないでしょうか。これはオブジェクトではありませんか?
  3. DoWork「 」、「 」などのメソッドを追加できますCalculate

これにより、より明確になります。

アップデート。上記のすべてについて議論することはできますが、私が本当に信じていることは、メソッド名に関係なく、コード内に十分なドキュメントを追加することで本当の違いが生まれるということです。

于 2016-02-09T10:36:34.403 に答える