関数オーバーロードとデフォルト実引数 解答ページ | Programming Place Plus Modern C++編【言語解説】 第10章

トップページModern C++編 C++編](../../index.html) – 第10章

Modern C++編は作りかけで、更新が停止しています。代わりに、C++14 をベースにして、その他の方針についても見直しを行った、新C++編を作成しています。
Modern C++編は削除される予定です。

問題①

問題① 2つの int型の値が同じかどうかは ==演算子で調べられますが、 const char*型で表現された2つの文字列の文字の並びが同じかどうかを調べるには ==演算子が使えません。 どちらでも使えるような equal関数を、関数オーバーロードを利用して作成してください。


たとえば、次のようになります。

#include <iostream>
#include <cstring>

namespace {

    bool equal(int a, int b)
    {
        return a == b;
    }
    
    bool equal(const char* a, const char* b)
    {
        return !std::strcmp(a, b);
    }
    
}

int main()
{
    std::cout << equal(10, 10) << "\n"
              << equal("abc", "abc") << std::endl;
}

実行結果:

1
1

引数が int型の場合と、const char*型の場合とでオーバーロードします。int型版は ==演算子を使い、const char*型版は std::strcmp関数を使って判定を行うようにしています。

問題②

問題② 次のプログラムの問題点を指摘してください(複数あります)

#include <iostream>

namespace {

    void func();
    void func(int a = 0);
    void func(int a = 0, int b);
    
    void func()
    {
        std::cout << "func()" << std::endl;
    }

    void func(int a = 0)
    {
        std::cout << "func(int)" << std::endl;
    }

    void func(int a = 0, int b)
    {
        std::cout << "func(int, int)" << std::endl;
    }
}

int main()
{
    func();
    func(10);
    func(10, 20);
}


関数オーバーロードと、デフォルト実引数を組み合わせて使っています。 これ自体は問題がない行為ですが、このプログラムには問題があります。

まず、3つ目の func関数の宣言ですが、

void func(int a = 0, int b);

1つ目の引数にデフォルト実引数を与えたのなら、それ以降の引数にもデフォルト実引数を与えないといけません。そのため、この関数はコンパイルエラーになります。

次に、main関数内の最初の func関数の呼び出しですが、これが曖昧になってしまっています。 func関数には、次の2つのオーバーロードがあります。

void func();
void func(int a = 0);

このようにオーバーロードとデフォルト実引数を組み合わせると、「func()」という呼び出しが、引数無しの func関数を呼ぼうとしたものか、デフォルト実引数を省略した呼び出しなのかが判断できないため、コンパイルエラーになります。このような形でのオーバーロードはしないようにすべきです。

最後に、func関数の宣言時と定義時の両方で、デフォルト実引数を使っていますが、 これは宣言時だけにしなければいけません。



参考リンク


更新履歴

’2017/7/28 新規作成。



第10章のメインページへ

Modern C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る