Accelerated C++ 第4章

見出しのつけ方をちょっと変更。

constでない参照パラメータ

const参照のパラメータが時間的、空間的な効率の点は良いとして、「constでない参照パラメータは左辺値でなければなりません」というのは実装依存だろうか?
コンパイラによってエラーにするかどうかが変わる(標準オプションで実施)

コンパイラ 組み込みの型(int) オブジェクト(vector)
Visual C++ エラー エラー・警告なし
g++ エラー エラー
bcc32 警告 警告

組み込み型だと、値の戻しようがないのでエラーだが、オブジェクト(クラス)だと一時オブジェクトへの書き込みが正しく行われるため、エラーとしないのかも。

//int
#include <iostream>
void add1(int & arg)
{
    ++arg;
}
int main()
{
    int     n;
    add1(n);
    add1(0);
}
//vector
#include <iostream>
#include <vector>
std::vector<int> emptyVec()
{
    std::vector<int> v;
    return v;
}
void add1(std::vector<int>& v)
{
    v.push_back(2);
}
int main()
{
    std::vector<int> newV;
    add1(emptyVec());

    return 0;
}

1つのステートメントには2つ以上の副作用を持たせない

なるべくシンプルなコーディングを。

一般にはヘッダファイルは必要な名前のみ宣言すべき

後の方にも書いてるけど、C++だとusing宣言がポイント。でも、そもそもnamespace知らないプログラマも多い。

課題

4-0

省略

4-1

本文にあるように宣言を正しく行うか、引数の型を、戻り値の型(intかstd::string::size_type)にキャストであわせる。

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::string name = "abc";
    int         maxlen;
    //std::max((int)name.size(), maxlen);
    std::max(name.size(), (std::string::size_type)maxlen);

    return 0;
}
4-2

元の値の出力前にsetw(4)、二乗の値の出力前にsetw(6)。

4-3

log10で桁数を取得して、4-2と同じ用に出力。

#include <iostream>
#include <iomanip>
#include <cmath>

void show(int n, int w)
{
    std::cout << std::setw(w + 1) << n << std::setw(w * 2 + 1) << n * n << std::endl;
}

int main()
{
    const int   i = 999;
    
    int digits = (int)log10((double)i) + 1;
    
    show(1, digits);
    show(i, digits);
    return 0;
}
4-4

実質整数なら4-3と同じでいける。実数なら「桁合わせ」をどうするか。

4-5,4-6,4-7

省略

4-8

[]が使用できる値を返すということだろうけど、この本でここまでの話だと、vectorが返される関数。素直に考えるとdoubleだけどintでも良い。

#include <iostream>
#include <vector>

std::vector<int> ifunc()
{
    std::vector<int>    v;
    v.push_back(1);
    return v;
}

std::vector<double> dfunc()
{
    std::vector<double> v;
    v.push_back(1);
    return v;
}

int main()
{
    double  d;
    d = ifunc()[0];
    d = dfunc()[0];
    return 0;
}