合計 昨日 今日

c++11 const参照の受け方について

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

返信する

Advanced BBCode Box 3 :: ヘルプ ページ Advanced BBCode Box 3 (aka ABBC3)  
選択テキストを切り取る (カット) 選択テキストをコピー コピーしたテキストを貼り付け (ペースト) 選択したテキストから全ての BBCode タグを削除します。 箇条書きリスト 連番付き箇条書きリスト リスト項目 水平線 太字 斜体 下線 取り消し線 上付き文字 下付き文字 フェードイン / アウト テキスト グラデーション 正当テキスト 左揃え 中央ぞろえ 右揃え 整形済みテキスト
タブインデント挿入 コード 引用 本題と外れた内容を囲むオフトピックテキストを挿入します。 Web アドレス Eメール 画像を挿入します。 サムネイル画像を挿入します。 Youtube 動画 を挿入します。 ニコニコ動画を挿入します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF
トピックのレビュー
このトピックは既に解決しています
   

展開ビュー トピックのレビュー: c++11 const参照の受け方について

Re: c++11 const参照の受け方について

投稿記事 by takashi » 2017年9月10日(日) 12:43

ありがとうございます。理解しました。
テンプレートについてはまだまだ浅い知識しかないので、
次はその辺りを勉強しようと思います。
ありがとうございました。

Re: c++11 const参照の受け方について

投稿記事 by tk-xleader » 2017年9月09日(土) 21:48

単にautoで変数を宣言すると、テンプレート関数の引数型と同じ規則によって変数型が決まります。例えば、
コード[C++]: 全て選択
1
template<typename T>void f(T arg){}
にint const&な値を渡した場合、argの型はconstも参照も外れた単なるint型になります。それと同じで、
コード[C++]: 全て選択
1
auto val = f();//const hoge& f();
とすると、変数valの型は単なるhogeになります。

関数の戻り値をconst&にするかどうかはケースバイケースなのですが、const&を返す場合は、関数内で寿命が尽きるオブジェクトを戻り値にしないように注意しなければいけないので、戻り値にできるのはグローバル変数、static変数あるいはクラスのメンバ変数くらいに限られます。

Re: c++11 const参照の受け方について

投稿記事 by takashi » 2017年9月08日(金) 01:25

返信ありがどうございます。
非常に参考になりました。

コピーコストを嫌がってconst参照で返しているなら、
受ける側もconst参照にした方が良さそうですね。

(1)で質問があります。
dectype(auto)ではなく(今回はC++11なのでそもそも使えないが)、
単にautoとして受けた場合、参照は外れてしまうみたいですが、
この場合は変数を変更できるということは、
const参照で返しても参照だけでなく、constも外れてしまうということでしょうか?
(3)は一時オブジェクトを参照で延命させているだけで、
一時オブジェクト自体の生成コストがかかってしまうのですね。

また、一般的にはコンパイラの最適化を期待して、
高速化のためだけだったら特にconst参照で返さないで、
コピーで返すのが普通なのでしょうか?

よろしくお願いします。

Re: c++11 const参照の受け方について

投稿記事 by tk-xleader » 2017年9月07日(木) 14:49

(1) 戻り値の受け取り方はケースバイケースで異なります。受け取った後でその変数を変更するつもりなら単にautoで受け取ることになります。戻り値を読み取りに使うだけなら余分な初期化が生じないconst&で受け取る方がいいでしょう。
(2) 単にautoと記述した場合には、テンプレート関数の引数推論と同じ規則で型が決定されるので、初期化値の型がconst&であっても変数がconst&修飾されることはないです。
(3) 戻り値が参照ではないのであれば、最適化を無視すれば戻り値のために一時オブジェクトが生成されます。したがってbar.fuga()は一時オブジェクトを生成してそれを返し、戻り値の一時オブジェクトをconst&で参照しているというコードになります。

c++11 const参照の受け方について

投稿記事 by takashi » 2017年9月07日(木) 01:29

c++でわからないことがあるので質問させてください。

ある関数があって、例えば

class Bar {
const std::vector<std::shared_ptr<hoge>& fuga();
}
のようなconst参照を返す関数があったとします。

このとき、この受け方なのですが、
実際にはRVOなどを考えるとそもそもconst参照で返す必要がないのかもしれないのですが、
(これについてもご意見を伺いたいです。)

もしこのような関数があったとき、受ける側は、

auto fuga = bar.fuga();

で受けるのか、

const auto& fuga = bar.fuga();

で受けるのとではどちらが良いでしょうか?

また、前者の場合は、fuga()がcons参照で返しているので、
そもそもauto fuga = bar.fuga();で受けた場合もconst auto fuga& = bat.fuga()
で受けた場合もまったく同じになりますでしょうか?
前者で受けた場合もconst参照になるのかが知りたいです。

また、c++では関数の返り値がconst参照でなかった場合
つまり
class Bar {
std::vector<std::shared_ptr<hoge>> fuga();
}
だった場合でも、
受ける側がconst auto& fuga = bar.fuga();だった場合はfuga()はコピーではなくてconst参照で返すのでしょうか?
(こちらもRVOを考えるとそもそもコピーは作られないのかもしれないですが、最適化は無効にしているとしたらどうなるでしょう)

以上の3点が知りたいです。よろしくお願いします。

ページトップ