質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

Q&A

解決済

2回答

6461閲覧

const参照と右辺値

Gaccho

総合スコア15

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Clang

Clangは、プログラミング言語 C、C++、Objective-C、Objective-C++ 向けのコンパイラである。

0グッド

0クリップ

投稿2018/07/15 15:04

編集2018/07/15 15:06

普段何気なく、C++11以降の環境で以下のようなコードを書いています。

cpp

1struct Int2 2{ 3 int var1{}; 4 int var2{}; 5 6 Int2() = default; 7 Int2(const int var_) :var1(var_), var2(var_) {} 8}; 9 10const Int2 func(const Int2& a,const Int2& b) 11{ 12 return Int2(a.var1 + b.var2); 13} 14 15int main() 16{ 17 const Int2 a = func(Int2(10), Int2(5)); 18 19 return 0; 20}

まだC++の知識が浅いのでとても怪しいですが、
上記のコードは違反的な書き方をしていないと思っています。

しかし、1つ疑問に思いまして
右辺値はconstの参照渡しの引数(ここでいう"const Int2& a")に渡しても問題ないでしょうか?

言葉が間違っていたらすみません。
また、上記のコードに問題点や改善点がありましたらどのように書くと良いのか教えていただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

に詳しく書いてるのまずそれを見てもらうとして、結論から言うと大丈夫です。const lvalue referenceはなんでも参照できます。

投稿2018/07/15 15:19

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

右辺値はconstの参照渡しの引数(ここでいう"const Int2& a")に渡しても問題ないでしょうか?

問題ないです。const参照は左辺値、右辺値のどちらでも受け取れます。

普通の参照は右辺値(というか一時オブジェクト)を受け取れないと決められていますが、const参照は受け取れると決められており、メジャーなコンパイラの新しいものはこれに準拠しています。

ただ、技術的には、普通の参照が右辺値を受け取ってもいいじゃないかとは感じます(VC++の古いバージョンはクラス・オブジェクトなら普通に受け取ります)が、きっと深い深い議論の結果受け取らない方が安全性が高くなると標準化委員会が判断したのだろうとも思います。

また、上記のコードに問題点や改善点がありましたらどのように書くと良いのか教えていただけると幸いです。

基本的には問題点はないように思います。人によって意見が分かれる部分はあります。

const Int2& aInt2 const& aと表記した方が恐らくバグが減る方向に多少近づくと思います。
前者はconstがInt2にかかるのかaにかかるのか混乱しやすい。後者も分かりやすいわけではないですが、C++の&*は後から前を修飾しているとも解釈できるので、これらは全て後から前へ修飾すると考えると、混乱が多少なりと減るからです。
次のような例を考えると特に。int const* constとか頭痛くなるけど、これは時々使います。これをconst int* constを書くとconstが何を修飾しているのか(intなのかint*なのか)訳わからなくなりそうです。

func()の戻り値をconst修飾しているのは不親切な印象を受けます。専用のオブジェクトを生成して返却しますから、非constでも特に問題はないケースがほとんどでしょう。
もし、このケースでも戻り値を呼び出し側で変更しても問題ないのであれば、呼び出し側の後続の計算過程で折角確保した記憶領域を変更できるようconst修飾しない方が使い勝手は良いと思います。
また、後続の処理で変更しない場合は、呼び出し側でconst修飾すればよいのですから、関数提供側がそれを強制しなくても良いように感じる次第です。

投稿2018/07/16 03:33

編集2018/07/16 03:36
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2018/07/16 03:42

pointer型は右側から解釈することを覚えておけば混乱はしないかなぁ
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問