27

StroustrupのC++プログラミング言語の本(第3版)の数値の章で、彼は次のコードスニペットを示しています。

void f(valarray<double>& d)
{
    slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
    slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];

    v_odd *= v_even;
    v_even = 0;
}

問題は、一時的なものv_evenv_oddの非定数参照であり、許可されていません。そして、これをコンパイルしようとすると、エラーが発生します。

error: non-const lvalue reference to type 'slice_array<double>' cannot bind to a temporary of type 'slice_array<double>'
    slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
                         ^        ~~~~~~~~~~~~~~~~~~~~~~~~

オンラインで入手できるすべてのエラッタを確認しましたが、この根本的な問題に触れるものは何もありません。私は何かが足りないのですか?本が印刷されてから(本自体が一時的なものへの非定数参照に対する規則に言及しているため)、この点で言語は変更されましたか?何が起きてる?


参照の代わりに値を使用するように関数を変更すると、たとえばslice_array<double> v_even = ...、これは実際にコンパイルされます。ただし、私のローカルC ++ヘッダーはコピーコンストラクターをパブリックにしますが、Stroustrupとさまざまなオンラインリファレンス(cppreference.com、cplusplus.com)は、コピーコンストラクターがプライベートであると主張しています。これは、このソリューションが移植性がないことを意味すると思います。これは、Stroustrupが非参照変数を含むコードサンプルを明示的にリストし、これがエラーを生成すると言っているという事実によって補強されています。


C ++ 98仕様(PDFslice_array<T> )は、プライベートコピーコンストラクターを持つことを宣言しています。2005年までに(この仕様によると)、おそらくC ++ 03の一部として、これはパブリックコピーコンストラクターに変更されました。

4

2 に答える 2

9

元のコードサンプルにはいくつかの異なる問題があるようです。また、多くの演算子について本に記載されている宣言もあります。

私が信じる「最良の」解決策は、次のようにすることです

void f(valarray<double>& d)
{
    const slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
    const slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];

    v_odd *= v_even;
    v_even = 0;
}

上のすべての演算子は、スライス自体ではなく、コンテンツを変更するものとしてslice_array<T>定義されています。constこれらは、本の中で非として誤って定義されていconstます。

于 2012-08-14T07:58:34.353 に答える
4

これは正誤表で公開されているようです(リンクは現在無効になっていますが)。

しかしグーグルは素晴らしいです、それはこの「slice_array&v_even」のような検索のためのスナップを示します

Stroustrup:C++プログラミング言語の3回目の印刷の正誤表
www.research.att.com/~bs/3rd_printing4.html
[キャッシュ][共有]Google+で共有。
投稿を表示します。
あなたはこれを公に+1しました。
元に戻す

void f(valarray<double>& d)
{
    slice_array<double>& v_even = d[slice(0,d.size()/2, 2)];
    slice_array<double>& v_odd  = d[slice(1,d.size()/2,2)];

    v_odd *= 2; // double ...

編集:-問題の編集をありがとうケビン、それはもうエラーではありません私は明確に言及されたN3092で見ることができます(§26.6.1、Pg944)

4.このような置換タイプを導入する実装は、次のように追加の関数と演算子を提供するものとします
。— const valarray&を使用するすべての関数に対して、置換タイプを使用する同一の関数を追加する必要があります。
—2つのconstvalarray&引数をとるすべての関数に対して、const valarray&と置換タイプのすべての組み合わせをとる同一の関数を追加する必要があります。

5.特に、実装では、そのような置換タイプからvalarrayを構築でき、 valarray、slice_array、 gslice_array、mask_array、およびindirect_arrayオブジェクトへのそのようなタイプの割り当てと計算された割り当てが可能になります。

さらに、私のコンパイラはコードに問題(現在はVS 2010)を与えておらず、完全にコンパイルされます。

于 2012-08-14T06:30:41.500 に答える