インクリメント後のイテレーターの値を返す処理の実装を考えると
先の場合はインクリメントしてそのまま渡せばいいけど
後の場合はインクリメント前の値を保存しといてそれを渡さないといけないので一手間かかるから
・・なんだけど諸々の最適化とか色んな条件とか考えたらそこまで差がでるかどうかはよくわからん
it++だと、戻り値をコピーしてとっておいてから、ポインタなりを進めた後にreturnする必要があるが、
++itだと、ポインタを進めた後に参照を返すだけでするからな。
>>398
ite++と++iteなんて気持ちの問題
てか範囲for文使えばいい どうせ戻り値捨てるんだったら++itを選んでおいて損はない
無駄にit++を使うのは時期尚早な最不適化って奴だ
C++で書くんだから後置インクリメントの方がメインに決まってんじゃん
前置は異端だ
C++でいいんだよ。
規格は一歩進むけど、使ってるやつはbetter Cばかりってな
>>411
vectorとかstringとか使わんの? CArrayとCStringだぞ
コピコンは定義されてないから自分で作るぞ
CArrayは、<algorithm>ヘッダーで定義された信頼性の高いユーティリティ関数を使えないのがね・・・。
>>415
イテレータをうまいこと定義すれば使えるやつも結構あるんじゃね?
そうでもない? inconsistent begin/end types in range-based ‘for’ statement
gcc(g++) 8.2で -std=c++17オプションでコンパイルで
範囲forでこのエラーが出るんだが
begin endの型不一致の制限緩和されいるはずだよな?
原因わかる方いますか?
>>415
GetData()とGetData()+GetSize()を渡せば、とりあえず動くんじゃね? >>422
int _n = 0;
auto __begin = _container.begin();
auto __end = _container.end();
for (; __begin != __end; ++__begin) {
_n = *__begin;
}
比較演算子はちゃんと定義してるし
上のコードは何故かコンパイル通る
だけど
for (const auto _n : _container) {
//hoge
}
は何故か通らない 範囲for文のconst autoをconst auto&かauto&&に変えるとどうなる?
>>424
auto&&にした時のみエラーが増えます
cannot bind rvalue reference of type ‘const long unsigned int&&’ to lvalue of type >>426
using iterator = typename std;;vector<int>::iterator;
using const_iterator = typename std;;vector<int>::const_iterator;
using my_iterator = MYIterator;
my_iterator begin();
iterator end();
const my_iterator begin() const;
const_iterator end() const;
const my_iterator cbegin() const;
const_iterator cend() const; これで動かん?
for (auto&& _n : _container) {
}
MYIteratorの実体がunsigned longみたいだけど
vector<int>::iteratorの実体がポインタだったらoperator!=の定義できなくない?
>>423
bool operator != (〜) const ← これ付け忘れてないか? >>427
自己解決
const iteratorとconst_iteratorが一緒だと勘違いしていた
const my_iteratorではなくmy_const_iteratorを実装して返り値とすべきでした struct A{
int member;
};
struct B: A{
void run(){member = 0;}//ok
};
template<typename T>
struct TA{
T member;
};
template<typename T>
struct TB:TA<T>{
void run(){member = 0;}//NG。this->memberとするとok
};
クラステンプレートを継承してクラステンプレートを作成した場合にthisでないと継承元のメンバーが見えないのは仕様?
仕様
一寸前までのmsvcではなぜか通っていたけど
>>437
2phase lookupだから
最初のTB解釈時にはTAが型引数一つのtemplate classであるという情報以外使わない
だいたいTAが特殊化される可能性があるだろ 8bitや16bitのintしか使えない環境で、
32bitなどの大きな数を扱うにはどうすれば良いですか?
変数をいくつかつなげて大きな数を表現できないかと思っているのですが、やり方が分りません。
ご存知の方いらっしゃいましたら教えて頂けると嬉しいです。
補足させて下さい。
足し算、引き算は出来るようにしたいです。
可能でしたら、掛け算や割り算もできると助かります。
>>438
> だいたいTAが特殊化される可能性があるだろ
なるほどそりゃそうか、サンクス karatsuba はかなり桁数が多いときじゃないと効果がないとも聞くけど
>>439
stdint.h で int_least32_t とか使えるのでは? >>446
8bit/16bit CPU で int_least32_t とかはそもそも存在しないのでは? >>447
「8bitや16bitのintしか使えない」を見て long や long long はもっと大きいんじゃないの?と思ったんだよ。
「整数型」の意味で"int"って書いてたんなら、確かに存在しない環境のことを言ってるのかもしれない。
その場合は ISO C/C++ の LONG_MAX の最低絶対値の要求に準拠できないってことになるんだけど。 8bit pic用XCでもlongは32bitなのに
>>449
それはそれですごいインプリメンテーションですね…
8 bit PIC で 32bit int がさくさく書けちゃうとは、そのインプリメンターは根性がありますね、それか頭のねじが何本か外れていて「無理を無理と思わない人」とか… shortは16bit固定でlongは32bit固定でしょ。何言ってんの?
>>451
残念でした、short も long もインプリメンターが好きに実装していいのですっ!きりっ! >>451
64-bit Linux でsizeof(long) が8だった。移植がある場合は<cstdint>使わんとあかん intが16bitならISOの規格は満たしてることになるかな。
32bit以上の長い整数はクラスと演算子オーバーロードで誤魔化すか。
頑張ってもリテラル表記もダメだろうから、使い勝手は悪いよな。
>>451
うろ覚えだが
VC Win32bit: int 32bit long 32bit pointer 32bit
gcc Linux32bit: int 32bit long 32bit pointer 32bit -ここまでは同じ
VC Win64bit: int 32bit long 32bit pointer 64bit -int64_tで64bit整数
gcc Linux32bit: int 32bit long 64bit pointer 64bit 厳密なbit長が必要なときにintだのlongだの使っちゃ駄目よ
intの配列のラッパーのようなものから再発明すりゃーいい
class Bignumber{
int number[4];
Bignumber(const String num){
for(int i=0; i<4; i++){
number[i] = //考えるのが面倒臭い
}
}
Bignumber operator+(){
//以下、延々とオペレータオーバーロードが続く
}
};
>>459
int64_t とか int32_t とか cstdint の面々を使うしかないでしょうね…私もデフォでそうするようになりました あ…ありのまま 今 起こった事を話すぜ。
平成の終わりにいろんな奴からshort/longに対する認識の誤りを指摘される恥辱を味わった。
何言ってるかわからねーと思うが(以下略
なんかもうビットという表現すら無くそうとしてるんじゃなかった?
制限された環境で使える多倍長整数のライブラリくらいいくらでもありそうだけど
>>462
なるほど、cstdint ですか!
教えてくださりありがとうございます ビット数を付けるのは、MISRA-C で決まっているだろ
int8, 16, 32
uint8, 16, 32
C++の規格上はintは16 bit以上(ターゲットのアーキテクチャで一番自然なサイズ
、longは32 bit以上
だったと思った
class ClassA
class ClassB: public ClassA
class ClassA::ClassC
のときに、ClassBはClassAのサブクラスと言いますがClassCはなんと呼ぶものですか?
>>469
>class ClassA::ClassC
この意味はなんですか? 基底クラス
スーパークラス
親クラス
ベースクラス
細かいことを言えば、規格準拠の処理系でも
int32_t (ピッタリ32bit) が定義されるとは限らないのね。
int_fast32_t, int_least32_t なら定義される。
8bit単位じゃないCPUへの配慮らしいから、
普通の(この表現も危険だけど)コンピュータを使う分には
int32_t があると仮定して書いてもたいがい大丈夫だろうけど。
コンパイルエラーが出るから出たら対処、で十分かと。
>>470
クラス内で定義したクラスです
class ClassA {
public:
...
private:
class ClassC;
ClassC * C;
}
class ClassA::ClassC {
...
}
の場合class ClassA::ClassC からClassA::を取るとコンパイルが通りません 「プログラミング言語C++」だと、入れ子クラス(nested class)とか
メンバクラス(member class)とか呼んでるみたい。
内部クラス(inner class)もよく聞くけど調べたらJava用語っぽいな
Inner Class、Java用語なのか。そう呼んじゃってたわ
>>473-474
nested class は仕様にあるので、
これが公式な用語と思って良いみたいだね。 以前、「完全さを求めるあまり今存在する良い物を犠牲にしてはならない」という趣旨のことわざをBBCハードトークで仄聞したのだが、原典はなんだろうか?
>>480
ググってヒットしたもののうち、これについてめぐらせています(ことわざとは関係ありません…)
http://www.kt.rim.or.jp/~hisashim/gabriel/WIB.ja.html
この人(原著者)、最後まで間違ったままでいるような気がしてなりませんが、実際のところどうでしょうか ストリームの遅さは凄い凄すぎる。
ほとんどの場合、遅くても問題ないということはわかる。
でもあそこ迄遅くする必要があったのだろうか。
今やどの言語もprintfのような書式付き文字列を指定する方式に回帰した(jsすら!)。
少なくとも書式付き出力に限れば、ストリームはプログラミング言語の中ではもう淘汰されてしまったんだと思うよ。
早いとこ、string::format()とかbasic_ostream::format()とか作ってほしいわ
多言語対応するためにはC#みたいに %1, %2みたいに引数を番号で指定できる書式じゃないとダメでしょ。
ストリームの精神はrangeに受け継がれて生き残るよ
だから書式はそろそろ負けを認めよう
<<には<<なりの良さがあると思うので、ストリームというより、stringがoperator <<をサポートすれば良いと思う。
文字列操作するためのインターフェイスとしては最悪だよ。
考えた奴は自分では絶対使わないで人に使わせるだけのタイプだろうな。
そもそもだけど、なんで文字って表示されるのに
<< とか %s とかこういうのが必要なの?
どの言語でもprint(a);だけで表示させればよくない?aが文字列でも整数でも小数でもさ。
引数で判断してくれよ。
>>493
え、そう?
文字列を連結する時に、+=と+を使い分けるより<<だけですむ方が楽だし、連結する順番も自明だし結構良くない?
std::string str;
str << "hoge" << 123 << ".txt";
みたいな。 >>492
それは私も考えていました、cerr に都度吐いているメッセージを、もう一度プログラムの最後にまとめて吐きなおす、とかをやってみたいんです… >>495
そのやり方は引数の順序を変えられないから語順が違う言語間での翻訳で困る コンストラクタの引数に出力先stringインスタンスを渡すostream派生クラスを作ればいいじゃない。
string str;
hogestream sstr(str);
sstr << "hoge" << 128;
>>499,500,501
ostream派生クラスじゃなくて独自のクラスのほうが軽量でいい。
stringインスタンスへのポインタのほかに、数値書き込み時の進数設定(oct,dec,hexを覚えておく)などをメンバ変数に持てばOK。 basic_ostream使えよっていつも思う
なんで決め打ちするのかわからない
b配列全てをa配列のケツにコピーするとき
std::vector<char> a;
char b[]={0,1,1,3,4};
a.insert(a.begin(),&b[0],&b[sizeof b]);
これでいいの?
&b[sizeof b]
これが死ぬほど気持ち悪いんだけど
そんな気色悪い書き方しなくてもこれでいいよ
a.insert(a.end(), std::begin(b), std::end(b));
>>508-509
std::copy に back_inserter を渡す方が効率的という豆知識。 >>511
insertのが速いんでね?
resizeしてmemcpyになるはず アルゴリズムよりvector::insertのほうが実装による最適化の余地は大きそうだな
ポインタがイテレータとして渡された時点で相手が連続バッファだってわかるからね
&b[sizeof b]でもstd::end(b)でもやってることは変わらないんだけどな
見映えは重要だな
sizeof bじゃcharでしか使えないんで、そういう意味でもイケてないかも
>>515
見栄えというか、名前が付いているってのはそれだけで単純にわかりやすいな。
(名前が妥当であれば。) 嫌儲で、東京五輪チケットのソースコードが出てるけど
C++使ってるお前らなら、こんなソースコードじゃないよね?
>>518
サーバーサイドあまりやってないけどこんな泥臭い書き方するのか こんなもんだろ
SIerが間違ってコンシューマ系のWeb制作を請けてしまうとこんな感じになる
てかこんなもの韓国に出すのね
安くなさそう
ってもしや北の方?
parseInt(Num).lengthって動かなそう
ほんまやw桁でも返ってくるのかと思ったがundefinedじゃんかw
型に無駄にこだわった結末がstreamと知っとくのは重要。
あの間違いを覚えとけ。
ゲームのシーンを管理するクラスとシーンクラスがあり、管理するクラスはシーンクラスを保持しています
シーンクラスから管理クラスのシーンチェンジを行う関数を呼び出したいのですがどうやったらいいでしょうか
シーンクラスが管理クラスのインスタンスを持ちたくありません
>>518
webにあげるなら難読化まではしないにしても最低限圧縮するよね >>526
シーンクラスに管理クラスへの参照(ポインタ)を持たせればいいんじゃないのか >a.insert(a.begin(),&b[0],&b[sizeof b]);
>
これ、添字オーバーしてるけどメモリエラーとかにならないの?
>>530
イテレータ範囲のendは配列の場合最後の要素の次のアドレス
それは普通の実装ではアクセスされることはない
規格的にも最後の次の要素へのポインタだけは未定義じゃない &p[N]はp + Nと同じって規格にあったっけ?
確かに&b[sizeof b]はデリファレンスしてるわ
これはあかんそう
>>533
a[i]は a+i ではなく *{a+i} 経験上出来るプログラマーは言語オタクが多いイメージ?(ただし浅い)
&*pはデリファレンスなしで単にpと評価するってどっかで特別に決められてなかったっけ?
>>530
int a[5];
int *p = &a[5];
というコードが有効、つまり
「配列の最終要素の次の要素」(現実には存在しないデータ)のアドレスを取れる、
という仕様から、この場合は許される、というのが >>531 の指摘か。
一般的に >>538 が成り立つなら便利だけど、調べ切れなかった。
流れの元になった >>508 を見返したら、
a.insert(a.begin(),&b[0],&b[sizeof b]);
これだと b[] の内容はベクタ a の先頭に挿入されちゃうね。 >>530
>>a.insert(a.begin(),&b[0],&b[sizeof b]);
>>
>
>これ、添字オーバーしてるけどメモリエラーとかにならないの?
508だけど、これは
a.insert(a.begin(),&b[0],&b[sizeof b]);
こっちの間違いです。ごめんなさい。
a.insert(a.end(),&b[0],&b[sizeof b]);
&b[sizeof b]);
この部分は
b+sizeof(b)
これなら問題ない感じ?
どちらでも動くけど、たまたまいてる可能性捨てきれないから不安なんだよね。
実際のソースはsizeof(b)がbに格納されているデータのサイズを示していて、
char b[256];
int s = read( fd, b, sizeof b);
a.insert(a.end(),&b[0],&b[s]);
みたいな感じで書いてます。
んで、b最大数来た場合にちゃんと動くか気になったというわけっす。
int s = read( fd, b, (sizeof b)-1);
無難にこれの方がいいですかね? >>539
>int *p = &a[5];
これは多分だめで、ポインタ値としての存在なら許される
int *p = a+5; ややこしいからoperator <<を定義しようw
VC++だと
std::vector<T> a; &a[a.size()]はoperator[]のassertionに引っかかるね
std::transformって並列処理されてますか?
c++17のparallel版使えば並列実行されるかもしれない
visual studioでC++17にしたけどいまいち並列版の使い方が分からなかった
普通にfor回すのと、OpenMP使ってfor並列化するのと、transform(非並列)使うの比較したら
OpenMP>普通にfor≧transform だった
struct AとAを継承したstruct Bがあって
Aの内容をBの共通部分にコピーする方法ってないですか?
A a;
B b = a;
みたいにしたいんですけど親を派生先にキャストはできないので困ってます
struct B : public A
{
B* operator=(const A& a){ this->hoge = a.hoge;}
};
これ初期時にも使えるんかな
コピーコンストラクタが実装できたとしてメンバ変数は1個ずつコピーするしかないですかね
スライシングをさせるとか?
安全に?スライシング起こす方法ってあったっけな?
なんか危ういからやろうともしなかったが
>>549
初期化時は普通にコンストラクタ初期化リストで A(a) って書けるでしょ。残りのメンバをどうするのか知らんけど。
代入なら static_cast<A&>(b) = a か b.A::operator=(a) で済みそう。 普通にコンストラクタかオペレーター作ればいいんじゃね
B::B(const &A)
B::operator =(const &A)
A::operator B()
雑なキャストでよければdynamic_cast<A>でおk
↑dynamic_cast<B>の間違い
B b = dynamic_cast<B>(a);
>>551
sturctでまとめればデフォルトコピーコンストラクタが使えるけどね。
あとはintとかPODオブジェクトだけだったらmemcpyしちゃうとかも、俺はたまにやるなw 549です
解決しましたありがとうございます
以下のように書いたら思っていたことが出来ました
(派生先のコンストラクタで親のデフォルトコピーコンストラクタ呼べるの知りませんでした)
代入は現状使う予定がないので大丈夫です
B::B(const &A a) : A(a) {}
引数付きコンストラクタって、=default使えるの?
厳密にはC++の質問になるのかよく分からないんですが……
C++プライマーで勉強しててconstexprの部分にさしかかったんですけどコンパイル時評価、コンパイル時に評価される……みたいなことが書いてあるんですがこれの意味がいまいちよくわかりません
実行時評価という言葉も見られるんですがそれぞれの違いとそもそも評価ってどういう処理のことなんでしょうか
それとそもそもconstexprの使いみちが分かりません
よろしくおねがいします。
>>563
評価=機械語による演算。
コンパイル時評価とは、コンパイラ(PCなど)が演算してその結果を成果物に出力すること。
実行時評価とは実行機(スマホなど)でプログラム実行時に演算して利用すること。 constexprってのは#defineの置き換えのために生まれたんだよ
C++11以前はenum使ってたんだけどなんかかっこわるいから専用のキーワードが出来たってことさ
1+2を計算するアプリ作るとするじゃん?
constexpr int a = 1 + 2;って書くじゃん?
でもこれaが3なの分かりきってるじゃん?
アプリをインストールした世界中のスマホでいちいち1+2=3って計算するの資源の無駄じゃん?
だからそういうコードを書いてコンパイルするとコンパイラが最初から「a=3」って埋め込んで世界資源の浪費を防ぐんだよ
これがコンパイル時評価
実行時評価は普通の電卓アプリがやってること
ユーザーが計算したいのは1+2か5×5かlog123456789かは使われてみるまでわからないので、おとなしくスマホのCPUと電池を使って計算する
これが実行時評価
const int n = 5;
const int m = n * 100;
要するにこうするとmを計算してくれる
別にビルド構成に組み込めば済む話じゃね?くだらないな。
そんなことしなくてもソースコード中に普通のコードと一緒に書けるから
constexprはtemplateと組み合わせたときに真価を発揮する。
templateを実体化するときに、型や非型引数に加えて、変数や関数なども活用して複雑な条件をつけ、
実体化するコードをカスタマイズできるようになるからね。
constexpre定数って配列の要素数に出来るということ以外に本質的な意味ってあるの?
そのへんがよくわからない
「constexpr 中3女子」でぐぐると変態コードがたくさん出てくるよ
constexpr int f();
constexpr int a = f(); //OK
const int b = f(); //NG
違いってこれだけでしょ
constexpr以前でも定数伝搬とか意識して書いてたところはあったはず、でもそれが本当に定数になっているのかはアセンブリ見ないと分からない
constexpr導入によってconstexpr変数の初期化は確実にコンパイル時に実行される、できなければエラー
同様の理由でconstexpr関数(コンパイル時にも実行可能な関数)が導入される
単なる#define定数の代わりとしても名前空間が使える分価値はあるし
例えばconstexprでCRCを計算すれば文字列switchが可能になるとか難しいけど便利ではある
それ普通にヘッダーファイル生成コードでも書いた方がいいだろ。。
そっちのが明らかに可読性、デバッグのしやすさ上だし。
こんなもんありがたがってるのはどうせmakeもまともに書けない連中だろう。
そうやって何十万ものヘッダファイルを生み出した例を知ってる。
>>583
c++の規格内で完結するのと、make等の外部ツールを使うのとでは移植性が全然違うよ。 同じ記述でソースコード内に式が書け関数が使えるメリットは可読性に大きく影響するだろうに
configure なんて外部ツールを使ったソースファイルやヘッダーファイルを生成しまくりですが、新しい車輪の再発明ですか?
configureは古い。GitHubやるならCMake一択。
configureより100億倍マシだとは思うけど
それはそうとしてwindowsでpkgconfig使わせて
CMakeって使いづらいよね
ターゲットの属性指定するのに
属性が先にくるんだもの
Visual Studio(C#)のプログラミングに関する質問です。
インクルードする2ファイルが、双方のクラスを互いに必要とするケースにおいて、
コンパイルが通らなくて困っています。(当たり前なのですが…)
【Aファイル】
クラスAの定義{
クラスBの使用(インスタンス作成、メソッド利用)
}
【Bファイル】
クラスBの定義{
クラスAの使用(インスタンス作成、メソッド利用)
}
【全体インクルードファイル】
#include Aファイル
#include Bファイル
【コンパイル結果】
Bクラスが存在しません(Aファイルにて)
【質問】
お互いにクラス定義を必要とする場合、
★具体的に★どのような実装をすれば良いのでしょうか?
本当に複雑な計算が必要な定数なんてそんな多くないだろうに。。
やっぱバカしかいねーのな。。
>>596
前方宣言ありがとうございます。猛烈に調べてみます。
indexという構造体を作ってstd::vectorにぶち込んだらgcc8でエラーになるのだが。
ダメなん?
ideoneでやってみると通るんだけどな。
そのままコピペしてもgcc8だと通らない。
なんやねんこれ。