6

これが悪い形式であり、宣言でデフォルト値を指定する必要があることは承知していますが、少しの間私を甘やかしていただければ..なぜこれはコンパイルされるのですか? そして、正確に何が起こっているのですか?

#include <iostream>
using namespace std;

class test
{
public:
    test(int n);
};

test::test(int n = 666)
{
    cout << n;
}

int main()
{
    test t;

    cin.sync();
    cin.ignore();

    return 0;
}

出力: 666

.. テンプレートは同じコードにどのように影響しますか?

template <class T>
class test
{
public:
    test(int n);
};

template <class T>
test<T>::test(int n = 666)
{
    cout << n;
}

int main()
{
    test<int> t;

    cin.sync();
    cin.ignore();

    return 0;
}

エラー:適切なデフォルト コンストラクタがありません

お時間をいただきありがとうございます!

4

2 に答える 2

4

C++ の仕様では、最初のケースが明確に許可され、2 番目のケースが許可されていないようです!

C++ 仕様 (§8.3.6/4) からの引用:

非テンプレート関数の場合、デフォルト引数は、同じスコープ内の関数の後の宣言に追加できます。

したがって、非テンプレート関数のように見えますが、後でデフォルトの引数を実際に導入できます。ただし、これがテンプレートで機能しない理由はわかりません!

于 2011-07-24T07:35:40.847 に答える
1

最初のケースは標準で許可されています。@Johannesから質問され、@Nawazから回答があったことを覚えています。(編集:ここに関連する質問があります)。

templateバージョンを許可しない理由は、template明示的にインスタンス化された場合にのみ関数が呼び出されるためです。あなたの場合、コンパイラは宣言を次のように見ます。

test<int> t;

-->編集: コンパイラによって異なる場合があります。gccでは問題なく動作します。<--

一部のコンパイラで機能しない可能性がある理由は、 as として明示的にインスタンス化していないためt(N)、コンパイラは解決できませんtest<T>::test(int n = 666)。したがって、引数のないデフォルトのコンストラクターを探しますが、見つかりません。したがって、エラーが発生します。

于 2011-07-24T07:44:42.507 に答える