web-dev-qa-db-ja.com

(参照)パラメータでconstを使用しない正当な理由は読みやすさですか?

いくつかの関数を書くとき、私はこのようなパラメーターにconstキーワードを見つけました:

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

IDEまたはvimで1行を2行に分割することがよくあるため、パラメーターのすべてのconstキーワードを削除します。

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

それがconstを使用しない正当な理由ですか?パラメータオブジェクトを手動で変更せずに維持することは可能ですか?

25
ggrr

読みやすさは、空白の使い方を学ぶ正当な理由です。

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

そこにあるパラメーターは、関数の本体と混同されません。別の行に配置することで、myFunctionの名前をわかりやすい名前に変更するときに、それらを再配置する必要がなくなります。パラメータが変更されていないときにパラメータの位置を変更しないことは、ソース管理の差分ツールでユーザーに評価されます。

constは何かを意味します。スペースやアイデアが足りないからといって捨てないでください。読みやすさは王様ですが、その名前を壊すことはあきらめています。

181
candied_orange

実際、読みやすさの問題は、確かに別の方向に向かっています。最初に、 空白の使用 によって実行ラインを簡単に解決できます。ただし、constを削除すると、行が短くなるだけでなく、プログラムの意味が完全に変わります。

Herb Sutterは、constへの参照をバインドできるため、constを参照するconst最も重要なconst として参照します。一時的なものであり、その寿命を延ばします。非constへの左辺値参照はできません。別の変数が必要です。

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

これがユーザビリティにとって意味することは、関数を呼び出せるようにするためだけに、これらすべての一時変数を導入する必要があるということです。これらの変数は無意味であり、署名が間違っているためにのみ存在するので、それは読みやすさにとっては素晴らしいことではありません。

52
Barry

簡単な答えは「いいえ」です。

長い答えは、constキーワードは関数が提供する契約の一部であるということです。引数は変更されないことを示しています。 constを削除した瞬間、保証はウィンドウの外に出ます。ドキュメント、規則、またはガイドラインを使用して、何かの一貫性(またはその他のプロパティ)を合理的に維持することはできないことに注意してください-コンパイラによって一貫性が強制されない場合、誰かwill 「ほんの少し」パラメータをいじれば、作業が簡単になります。考慮してください:

_// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);
_

後者のバージョンの方が簡潔であるという事実は別として、より強力なコントラクトを提供し、コンパイラーが意図を維持するのに役立ちます。前者は、fna(Foo&)関数が渡したパラメーターを変更するのを防ぐために何もしません。

@CandiedOrangeの回答のように、空白を使用してコードをレイアウトし、読みやすくすることができます。

21
Mael

constキーワードの削除可読性を削除constは情報をリーダーとコンパイラに伝達するため。
コードの水平方向の長さを減らすことは良いです(誰も横にスクロールするのが好きではありません)が、テキストよりconstのほうが便利です。あなたはそれを書き直すことができます:

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

これは契約を変更しませんが、行の長さを短くする必要を満たします。本当に上記のスニペットは読みにくくなると思いますで、CandiedOrangeの回答ですでに述べたように、より多くの空白を使用することを選びます。

constは、コード自体の機能です。宣言のMyClass::セクションを削除するために関数を非メンバーにしないので、constを削除しないでください

14
Erdrik Ironrose

可読性は、パラメーターでconstを使用しない正当な理由ですか?

いいえ。constを省略すると、機能が変更され、constが提供する保護機能が失われ、効率の悪いコードが作成される可能性があります。

パラメータオブジェクトを手動で変更せずに維持することは可能ですか?

時間を費やすのではなく手動コードのフォーマット

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

自動フォーマットツールを使用します。 functional要件に従って関数を記述し、自動フォーマットでプレゼンテーションを処理します。手動でフォーマットを調整することは、自動フォーマットを使用したり、節約された時間を使用してコードの他の側面を改善するほど効率的ではありません。

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}