X



C++相談室 part131 [無断転載禁止]©2ch.net
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん 転載ダメ©2ch.net (ワッチョイ 3b96-ov1m)
垢版 |
2017/07/29(土) 11:28:28.97ID:o30VDF4g0
次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part130
http://mevius.2ch.net/test/read.cgi/tech/1490917669/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.100【環境依存OK】
http://echo.2ch.net/test/read.cgi/tech/1478440682/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
-
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
0900デフォルトの名無しさん (ワッチョイ 76b3-yS8h)
垢版 |
2017/10/06(金) 21:08:44.42ID:vfMxTM1h0
→ の意味教えて下さい。
0906デフォルトの名無しさん (ワッチョイ 1ab3-3Fj1)
垢版 |
2017/10/07(土) 01:41:08.30ID:6wfQSWva0
質問です
以下のコードがコンパイルに通りません
class Structure { public: std::string type; };
std::vector< std::unique_ptr<void> > data;

std::unique_ptr<void> structure(new Structure);
structure->type = "HogeHoge";
data.push_back(structure);

>g++ -Wall -std=c++11 -c hogehoge.cpp
>error: ‘std::unique_ptr<void>::pointer {aka void*}’ is not a pointer-to-object type
> structure->type = "HogeHoge";
> ^
std::unique_ptr<void>ではなくて、
std::unique<Structure>にするとコンパイル通りました
voidだとだめなんでしょうか エラーになる理由を教えて下さい
0909デフォルトの名無しさん (ワッチョイ b632-rzHd)
垢版 |
2017/10/07(土) 08:30:30.38ID:r58+Koxz0
>>906
エラーメッセージに書いてあるだろ
structure->type = "HogeHoge"; の代入先がオブジェクトじゃねえぜと
おまえさんはvoid = char const*;をやろうとしたんだよ
0910デフォルトの名無しさん (ワッチョイ b632-rzHd)
垢版 |
2017/10/07(土) 08:31:55.56ID:r58+Koxz0
あ、すまんちょいミスった
指摘できるやついる?解説頼むわ
0913デフォルトの名無しさん (ワッチョイ b651-iGo5)
垢版 |
2017/10/07(土) 09:03:55.62ID:7nonADk70
unique_ptr<void>という型なので、
中にtypeというメンバーがあることがコンパイラからはわからない。

static_cast<Structure*>(structure.get())->type = "HogeHoge";
のように明示すればコンパイルだけは通るかと思ったんだが、
こっちだと>>911の問題に引っかかって、その前の行でエラーになる。
0916デフォルトの名無しさん (ワッチョイ dae7-XSap)
垢版 |
2017/10/07(土) 11:58:47.95ID:rHfSD+zL0
>>913
delete できないからね
voidを渡すんならカスタムデリータもセットにしなきゃならない。

template <typename T>
struct vp_deleter {
void operator ()(void *p)const
{
delete static_cast<T*>(p);
}
};

std::unique_ptr<void, vp_deleter<int>> a(new int(8));

なら通った。
0918デフォルトの名無しさん (ワッチョイ 1ab3-3Fj1)
垢版 |
2017/10/07(土) 12:36:08.56ID:6wfQSWva0
>>907
anyは知りませんでした
stdじゃなくてboostにあるんですね つかってみます
>>909
つまり void*->type は void.type になるってことですね
voidポインタは使ったことなくて、あれから調べたのですが
アクセスする前にキャストが必要だと知りました・・
無知ゆえの初歩的なミスです 指摘ありがとうございます
>>911, >>913, >>916
スマートポインタなのでデストラクタを呼び出せるようにしないといけないんですね
カスタムデリータは知りませんでした コード参考になります

void型なのはStructureの他にもプリミティブ型とかも入れたかったからです
boost::any使うやり方とカスタムデリータ渡すやり方両方やってみます
皆さんレスありがとうございました
0921デフォルトの名無しさん (ブーイモ MMfa-0mrS)
垢版 |
2017/10/07(土) 14:17:50.50ID:jvf7kHO4M
ある配列がありそれを指定した順番で並び替えしたい

std::vector< any_struct_t > array; //これを並び替えたい
std::vector< unsigned int > index_list = { 3,8,6,0,2...}; //この順番にしたい

探しているんだけど適当なライブラリが見つからない
標準ライブラリに入ってたりする?
またはアルゴリズムが知りたい
出来ればswap回数が少ない方法が知りたい
0922デフォルトの名無しさん (ササクッテロリ Sp75-o/K3)
垢版 |
2017/10/07(土) 15:34:33.81ID:cqowZFEsp
配列もう一個用意してその添え字に移動するんじゃだめなん
0925デフォルトの名無しさん (ブーイモ MMfa-0mrS)
垢版 |
2017/10/07(土) 16:25:34.07ID:jvf7kHO4M
>>924
それタイプミスあります?
でももう一つ配列を用意してコピーする点では
他の方と一緒ですね

別配列を用意せず全てswapで済ます方法も作ってみましたが
これにはindex_listが更に2本必要になり
効率は別配列と変わらないと予想される結果でした

参考になりました
ありがとうございました
0934デフォルトの名無しさん (ワッチョイ b651-iGo5)
垢版 |
2017/10/07(土) 19:11:01.43ID:7nonADk70
屁理屈を言うと、index_listを壊していいなら、
以下の手順で別領域を使わない置換は可能。遅いけど。
for( size_t i = 0; i < array.size() - 1; ++i )
{
std::swap( array[i], array[index_list[i]] );
std::swap( index_list[i], *std::find( index_list.begin()+i+1, index_list.end(), i ) );
}
0946デフォルトの名無しさん (ワッチョイ b651-iGo5)
垢版 |
2017/10/07(土) 23:13:09.50ID:7nonADk70
>>934
別領域を使わない置換に再挑戦。今回はO(n)のはず。
for( size_t i = 0; i < array.size() - 1; ++i )
{
size_t j = i, k = index_list[i];
while( k != i )
{
std::swap( array[j], array[k] );
index_list[j] = j; j = k; k = index_list[k];
}
index_list[j] = j;
}
0949デフォルトの名無しさん (ワッチョイ b651-iGo5)
垢版 |
2017/10/08(日) 06:22:19.14ID:+SudLjvR0
>>947
以下の2つの理由により、外側のループがn回まわる間に
内側のループの中身はたかだかn回しか実行されない。
1. 内側のループ内で処理済みのインデックスjに対し index_list[j]=j が実行される。
2. index_list[i]==i の条件が最初から満たされていた場合、内側のループは実行されない
要するに、内側のループを実行済みかのフラグとしてindex_listを使ってるだけ。
>>948
index_listを壊している時点で屁理屈なのは自覚しているんで、仕方ない。
一応、別配列にムーブする場合と比べると、
最初から正しい位置にある要素への処理が不要になるというメリットは有る。
0951デフォルトの名無しさん (ワッチョイ b651-iGo5)
垢版 |
2017/10/08(日) 11:34:33.36ID:+SudLjvR0
駄目な理由が引数を壊すってことだけなら、引数を値渡しにしてやれば、
呼び出し時に勝手にコピーされるので問題ないはず。
壊していい引数を渡す時はstd::move()すればいいし。
0952デフォルトの名無しさん (ワッチョイ aaeb-qWqy)
垢版 |
2017/10/08(日) 13:39:35.60ID:GUxnbDfL0
引数がconst参照=引数の状態を変更しない(てか、できない)という意思表示
に対して
引数が右辺値参照=引数の状態を変更する(しても文句言うな)という意思表示
というのはアリ?

右辺値参照に対する理解が曖昧なんで漠然とよく分からない(何が分かって
ないかも分からないw)んだが、もっと別な意思表示方法もある?
0956デフォルトの名無しさん (ワッチョイ dabd-mvC5)
垢版 |
2017/10/09(月) 09:00:03.09ID:U0LcPFS10
右辺値参照というのは、関数f()へのT型データの値渡し時に暗黙のうちに行われる(C++03までは無条件に行われていた)
 (左辺値) = (右辺値)
という代入処理において、
当該代入処理後、右辺値が関数呼び出し元によって使われなくなることが明白なとき、
 左辺値へのコピー後、右辺値をデストラクトする
という処理に暗黙のうちになっていたものを、
 右辺値から左辺値への移動
と「も」書けるようにするためのしくみ

Tに効率の良いムーブコンストラクタ(か右辺値参照を引数とする代入演算子)を定義しないとメリットが生じない
ポインタに__restrictを付けるべきかどうか悩まねばならないレベルの人用
C++03でもコンストラ・デストラ呼び出し回数削減の最適化がかかって同じような効果になるケースが多々あるから
そういうのが信用できない神経質な人向け

※ 個人の感想です
0958デフォルトの名無しさん (ワッチョイ dabd-mvC5)
垢版 |
2017/10/09(月) 09:20:15.73ID:U0LcPFS10
>>957
右辺値参照には一時オブジェクトしか代入できない縛りがあるから_
関数fooを
 voiid foo(int&& x)
というバージョンしか定義していないとすると、
 int g_x = 10;
 foo(g_x);
がビルドが通らないのではないか;
一般的な使用を想定すれば、結局foo(const int& x)も定義必要

C++03までしか使ったこと無いから知らんけど;;
0969デフォルトの名無しさん (ワッチョイ dab3-Nz6W)
垢版 |
2017/10/09(月) 20:56:32.03ID:UEIAYP2F0
>>968
> 理解してないのでなにを指摘してるかさっぱり分からないが、
わからないなら絡んでくるなよ...

> つまり、気取ってC++でGCっぽいことしようとして破綻してるわけだな。
全然違うし
0973デフォルトの名無しさん (ワッチョイ b183-wbjw)
垢版 |
2017/10/09(月) 21:56:43.96ID:bLguG3ky0
ところでなんでそんなに一時オブジエクトを参照しなきゃいけないコードを書くの?
参照元を管理するのが面倒だから? そういう人は初めからGC言語使えばよくね? ということですか?
0974デフォルトの名無しさん (ワッチョイ 958a-ZNcz)
垢版 |
2017/10/09(月) 22:03:17.69ID:Rk3/uNWr0
なんでとか言われても。。。
壊してもいい一時オブジェクトの場合、特別に効率的な扱いをしたくなるケースなんて山ほどある
それが分からないならC++なんて触らずにGC言語専門でやってればいいと思うよ
0975はちみつ餃子 ◆8X2XSCHEME (ワッチョイ ae6f-XSap)
垢版 |
2017/10/09(月) 22:10:35.64ID:GeS0S50a0
そのあたりはトレードオフなんだよ。
そりゃあ気にせずに済むなら気にしたくないが、気にしなきゃならないときに出来ることがないのはつらいって話で。
0984デフォルトの名無しさん (ワッチョイ dae7-XSap)
垢版 |
2017/10/09(月) 23:09:59.39ID:1ynB1O3m0
んん?
右辺値を束縛したい(一時オブジェクトだから左辺値としての実体はない)
けどconst左辺値じゃダメ(中身を変更したいから)
 ↑
これのどこにわかりにくい点があるというのか?
「RVOが保証されるようになったらいらない」という意見なら理解できるが・・・
0986デフォルトの名無しさん (オッペケ Sr75-BFoK)
垢版 |
2017/10/09(月) 23:16:20.29ID:7RyTvmhPr
>>973「なんでそんなに一時オブジエクトを参照しなきゃいけないコードを書くの?」
 ↓
>>984「右辺値を束縛したい(一時オブジェクトだから左辺値としての実体はない)けどconst左辺値じゃダメ」
 「これのどこにわかりにくい点があるというのか?」

これがアスペというやつか
0994デフォルトの名無しさん (ワッチョイ dabd-mvC5)
垢版 |
2017/10/09(月) 23:41:18.28ID:U0LcPFS10
>>986
右辺値を束縛したい文脈ではかわりにconst左辺値で常におkなのでは…(ていうかconstはあってもなくても良い

>>985
T型データのswapは素朴にはT型データのコピー3回+破棄2回ぐらいが生じる
のでわ…
レス数が950を超えています。1000を超えると書き込みができなくなります。

ニューススポーツなんでも実況