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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Visual Studio

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

C++

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

Q&A

解決済

1回答

1643閲覧

関数の引数をCONSTのリファレンスにするとエラーが発生する

saku26

総合スコア7

Visual Studio

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

C++

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

0グッド

0クリップ

投稿2021/06/12 14:05

C++の初学者です。
Visual Studio 2017で、VC++でコンパイルしています。

以下のコードは実行できるのですが、

C++

1#include <iostream> 2#include <array> 3 4template < typename T, std::size_t N > 5struct array 6{ 7 using value_type = T; 8 using reference = T & ; 9 using size_type = std::size_t; 10 11 size_type size(){return N;} 12 13 value_type storage[N]; 14 reference operator [] (size_type i){return storage[i];} 15}; 16 17template < typename Array > 18void print(Array & c) 19{ 20 for (std::size_t i = 0; i != c.size(); ++i) 21 { 22 std::cout << c[i]<< "\n"; 23 } 24} 25 26int main() 27{ 28 array<int, 5> a = { 1,2,3,4,5 }; 29 print(a); 30}

関数printのリファレンス引数cについて、値を変更できないようconstにするとコンパイルエラーとなります。原因と解決方法を教えてください。

void print(Array const & c)

◆エラーメッセージ
__Severity Code Description Project File Line Suppression State
Error C2662 'array<int,5>::size_type array<int,5>::size(void)': cannot convert 'this' pointer from 'const array<int,5>' to 'array<int,5> &'

Severity Code Description Project File Line Suppression State
Error C2678 binary '[': no operator found which takes a left-hand operand of type 'const array<int,5>' (or there is no acceptable conversion)__

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

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

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

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

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

guest

回答1

0

ベストアンサー

#include <iostream> template <typename T, std::size_t N> struct array { using value_type = T; using reference = T &; using size_type = std::size_t; size_type size() const { return N; } value_type storage[N]; const value_type operator[](size_type i) const { return storage[i]; } }; template <typename Array> void print(Array const &c) { for (std::size_t i = 0; i != c.size(); ++i) { std::cout << c[i] << "\n"; } } int main() { array<int, 5> a = {1, 2, 3, 4, 5}; print(a); }

直してみました。
constにする場合、その関数の中で呼び出すconst変数のメソッドを全てconstにする必要があります。
この場合、sizeoperator[]が該当します。
あと、operator演算子の定義が違うと思います。value_typeを返すべきです。
また、#include <array>は今回不要です。ソースコードの中でarrayを定義しているためです。

投稿2021/06/12 14:16

編集2021/06/12 15:04
fukatani

総合スコア626

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

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

episteme

2021/06/12 14:59

> まずArray constではなくて、const Arrayです。 どっちでも構わんのじゃない?
fukatani

2021/06/12 15:02

確かにそうですね、ありがとうございます。直します。
saku26

2021/06/13 00:17 編集

ご回答ありがとうございます。 printの引数をconstにする場合、引数側のarray classのメンバー関数(メソッド)を全てconstにする必要があるということですね。理解しました。 理解できていない点が1つあります。 operator [] は、array storageをコピーしないように意図的にlvalue referenceにしていたのですが、 using cost_reference = const T & ; cost_reference operator [] (size_type i) const {return storage[i];} として、lvalue referenceをconstにしても動作するようです。 これは問題ない使い方でしょうか? そもそも、operator [] をlvalue referenceにしなくても、array storageはコピーされないでしょうか?
episteme

2021/06/13 01:11

> using cost_reference = const T & ; > cost_reference operator [] (size_type i) const {return storage[i];} 僕はこう↑します。コピーがコスト高な要素をarrayに収めることを考えると。
saku26

2021/06/13 03:51

epistemeさま、ありがとうございました。 operator []をconstのlvalue referenceする考え方、方法は using cost_reference = const T & ; cost_reference operator [] (size_type i) const {return storage[i];} これで問題ないということですね。 よくわかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問