2012-08-14 5 views
26

ニューメリックスの章では、彼は次のコードスニペットを示し、Stroustrup氏のC++プログラミング言語の本(第3版)では:問題はされていない、v_evenv_oddが一時に非const参照で、あるStroustrupは非const参照を一時的にどのように受け取りますか?

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; 
} 

を許可されます。そして、これをコンパイルしようとすると、エラーを発する:

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仕様(PDF)は、プライベートコピーコンストラクタを持つものとしてslice_array<T>を宣言します。 2005年(this specによる)、おそらくC++ 03の一部として、これはパブリックコピーコンストラクタに変更されました。

+0

"この本は印刷されて以来この点で言語の変更がありました。" "参照バインディングルールは非常に古いものです。 'valarray'は最近です。それはエラーのように見えます(BSによる)。 – curiousguy

+0

@curiousguy:この本は20回印刷されました。私はすべての正誤表を見渡した。 2回の印刷でこの機能が変更されましたが、面白いことに、2回目の変更が最初の変更を実際に元に戻しました。どちらの変更も当面の問題に関連していませんでした。 –

+2

"_本は20回印刷されました._"収束し始めますか? – curiousguy

答えて

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; 
} 

彼らはスライス自体を変更していないようconstのように定義されているslice_array<T>上のすべての事業者が、その内容を以下のように行うことです。これらは、本の中で非constと誤って定義されています。

4

これはエラッタで公開されているようです(リンクは現在死んでいますが)。

Googleは素晴らしいですが、それはこの「slice_array & v_even」

Stroustrup: Errata for 3rd printing of The C++ Programming Language
www.research.att.com/~bs/3rd_printing4.html
[Cached][Share] Shared on Google+.
View the post.
You +1'd this publicly.
Undo

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 ... 

EDITような検索のためのスナップを示しています - 質問ケビン・編集のためのおかげで、それはもはやエラーではありません 私は私のコンパイラは(presentlをすべての問題を与えていない、さらに

4. Implementations introducing such replacement types shall provide additional functions and operators as follows:
— for every function taking a const valarray&, identical functions taking the replacement types shall be added;
— for every function taking two const valarray& arguments, identical functions taking every combination of const valarray& and replacement types shall be added.

5. In particular, an implementation shall allow a valarray to be constructed from such replacement types and shall allow assignments and computed assignments of such types to valarray, slice_array, gslice_array, mask_array and indirect_array objects.

(26.6.1、Pgの944条)明確に言及したN3092で見ることができますy VS 2010)をコードと組み合わせて、完全にコンパイルします。

+0

参照されているページは実際には[ここ](http://www.stroustrup.com/3rd_printing4.html)であり、 'f()'を...に変更して、関数の正確な複製を出力します。 –

+0

私は事がGoogleキャッシュされたものが更新されたと思います、文書をシフトしながらいくつかの(Ctrl + C、Ctrl + V)エラーかもしれません;) – perilbrain

+3

msvcは一時的でない参照を誤って持つことができます。 – PlasmaHH

関連する問題