メンバに自クラスの配列を持つクラスのメンバ配列の初期化はc++ではどうやりますか?Javaでは下のように出来てます。
☆Javaでこうなっています
class A {
protected A[] node = new A[3];
}
☆c++でこうしたらエラーになりました。
@a.hpp
class A {
public:
static A node[];
};
@a.cpp
#include "a.hpp"
A A::node[] = new A[3];
ちなみに型Aを適当にintとかにしたらc++の方もいけました。
>>7
nodeは静的メンバ変数でいいの?
java同様、staticはすべてのクラスインスタンスで共通の変数って意味だけど。 >>8
ダメだとは思ってましたが、つけないと不完全な型名は使用できませんと怒られました。
c++ではメンバに自クラスの変数がいるとダメなのですか? うまくいく例
class A {
public:
static A *node;
};
A *A::node = new A[3];
staticにしない例
class A {
public:
A *node;
A();
};
A::A() {
node = new A[3];
}
>>9
> c++ではメンバに自クラスの変数がいるとダメなのですか?
そりゃだめだよ、もしそんなのができたら
class A {
A a;
int b;
};
A x;
とした時に x.b; x.a.b; x.a.a.b; ... みたいに無限に int b; を作る羽目になるから。
Javaなどは
class A {
A *a;
int b;
};
みたいなのしかできないから問題ないだけ。 C++のクラス変数とJavaのクラス変数の違い、だっけ。
端的に「C++ではnewなしにクラス変数を宣言して使える」ようにするため。
Javaと対比しながら説明する能力がないんで中途半端で悪いけど。
× 変数を宣言
○ 変数を定義
中途半端な上に間違っててすまぬ。
あまつさえ細かい訂正のために貴重な投稿枠の浪費までも。
>>14
クラス変数の問題ではなく、クラスのメンバとして配列を宣言した場合にC++では配列の実体をメンバとして持つのに対し、Javaでは配列の実体は別のところに作られて参照だけを持つというところでないの? 7の人です
みなさんありがとうございます
別のやり方考えます
>>16
配列は関係ない
C++はクラス型のクラス変数を定義すると実体を持つから自分自身を定義できないってだけ
JavaやC#は実体じゃなくてポインタを持つだけだから問題ないってこと enum {hoge, fuga, hage};
で
hoge==0
fuga==1
hage==2
として使えるとして
0,1,2とかの数字から実行時にhoge,fuga,hageの名前を知りたい時って
何か便利なインターフェースありますか?
みんな毎回線形探索のコード描くみたいにやってる?
>>23
連番なら配列に入れときゃいい
番号飛んでいて…
・件数少ないなら線形サーチ
・件数多いならハッシュとかバイナリサーチとか >>23
VSだったらデバッガで名前表示されるけど
あれ列挙に名前までつけた時だけだっけな 連番じゃないときとか
結構でかい番号だったりするときは困りますね
実行時に列挙定数の名前の文字列が欲しいことがそんなにあるかな?
デバッグプリント用途くらいしか思いつかんのだけど。
vector<int> a = {8, 1, 9, 5, 7, 3};
があるときに例えば
vector<int> b = a{0, 2, 5};
とかしたら
b が {8, 9, 3} の配列みたいになってくれる書き方ってありますか?
vector<int> b = {a[0], a[2], a[5]};
>>31 for(int& e: b) e = a[e]; >>23
msvc/clangのc++17限定でよければ、nameof c++というライブラリがある。 >>33
https://ideone.com/x0lKkD
で
for(auto t: {indices...}) std::cout << source[t] << std::endl;
だと動くのですが
for(T t: {indices...}) std::cout << source[t] << std::endl;
だとエラーになります
どうして? >>36
エラーメッセージを見ればわかるやろ。
T はパラーメーターパックであって、展開せずに使うということはできへんのや……。 テンプレートが型付マクロにしかみえません
眼科に行った方が良いですか?
マクロといってのcのマクロではなくlispのマクロ的な機能
まあコンパイル時の制限はあるけど
Win32APIでコンボボックスの値をオーナードローしているんですが、wchar_tで項目追加すると文字の描画ができるんですが、
c_str()だと文字化けします。何故ですか?
・WM_INITDIALOG
文字化けしないケース
const wchar_t *a = L"あいうえお";
SendMessage(hForeColor, CB_ADDSTRING, 0, LPARAM(a));
文字化けするケース
std::wstring b = L"あいうえお";
SendMessage(hForeColor, CB_ADDSTRING, 0, LPARAM(b.c_str()));
・WM_DRAWITEM
DrawText(lpDraw->hDC, (wchar_t*)lpDraw->itemData, -1, &r2, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
オーナードローの時、CBS_HASSTRINGSスタイル指定しないと、そんな感じになるっぽいね
CB_ADDSTRINGメッセージに書いてあるね
1つの言語をある程度やりこまないと能力値がリセットされますか?
理解する能力と
使いこなす能力と
創造する能力は
全部別
リセットはされない。
複数言語を学ぶときは並行にやって混乱するか順番にやって混乱するかのどちらか。
自分に向いた方を選べ。
ある程度やりこまなければある程度落ちるのは常識
ある程度やりこめばある程度上がるのも常識
>>45
リセットされたのではなく、自分が理解できていたと思い込んでいただけで実際の理解がその程度だったということに気づかされただけだと思うぞ。 fopenでccs=utf-8を指定して改行コードのCRLFをfputwsで書き込んだら
CRCRLFになったんですけど。バグですか?
>>52
WindowsではLFがCR LFに変換されるので、仕様ですよ。
CRを出力しないか、バイナリファイルとして出力して下さい。 バイナリじゃなく、テキスト処理してる場合は、
各OS のAPI を使った時に、
Windows なら、CRLF になって、
Linux なら、LF になるのだろう
Ruby でもそう。
Windows にインストールしたものは、CRLF になって、
Linux にインストールしたものは、LF になる
LFがCRLFになるんじゃなくて\nがCRLFになっただけじゃないのか?
Global New Line みたいな指定もある。
\n が、OS によって自動的に切り替わるもの
Windows なら、CRLF になって、
Linux なら、LF になる
\nはコンパイラが読み込んだ時点でLFに変換される
そうでないと、'\n'みたいな文字を読み込んだ時に
保存に2バイト必要になってしまう
C++のenumの仕様について質問させてください
enum Aとenum Bが定義されていた時、
void func(enum A);
void func(enum B);
のようにオーバーロードできるでしょうか。
最近C++勉強し始めて疑問に思ったので教えて下さい
std::vector<int>vec;
auto result = std::find(vec.begin(), vec.end(),3);
上記のようにvectorを宣言だけで初期化せずにfind関数内でbegin()、end()を使用しても例外が発生しません
これは範囲外の要素にアクセスしているわけじゃないという理解でよろしいでしょうか
そうだね
というか最初はbegin=endだから、findで一度もループ処理が発生しないだけ
>>68
自分で明示的に初期化していないだけで、vectorの変数を宣言しただけで勝手に(サイズが0のvectorとして)初期化してくれる。
vectorのコンストラクタがそれをやってくれている。 >>69-70
わかりやすい説明ありがとうございました
なんかスッキリしました #include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int>vec;
vec.reserve(10);
auto result = std::find(vec.begin(), vec.end(),3);
std::vector<int>vec2;
vec2.resize(10);
auto result2 = std::find(vec2.begin(), vec2.end(),3);
return 0;
}
下火っていうか
調理場にあるラップのようなもので特に意識されることはないけど欠かすことのできないもの
でもラップを使った料理っていうとどうしてもお手軽感がぬぐえない
プロの調理師はこういうものはできるだけ人目につかないようにする
聞き方が悪かった
boostは習熟したほうがいいですか?
boostじゃなくても同じことが出来るものがあったら後者を選ぶな
なんでだろ自分でもわからんω
いまならasioなどのために使うのでは。
そしてネットワーキングTSが標準に入ると、また使わなくなる。
そういうサイクルがあるのでは。
>>42
win32api使うならTCHAR使いましょうよ MBCS対応する気ないならTCHAR使う意味ないよ
MBCS_Support_Deprecated_In_MFCだし
WCHAR決め打ちで行くんならDrawTextWにしないと
Debianがgcc8なのでfilesystemをboostのほう使うとか。
互換性が動機という場合もありますね。
C++ の仕様に関する質問です。
OpenGL では、
typedef unsigned char GLboolean;
#define GL_FALSE 0
#define GL_TRUE 1
void glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const void *pointer);
となっていますが、
glVertexAttribPointer(locAttr, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
と書いた場合、第四引数の GL_FALSE は 0 なので、int 型の整数リテラル(32BIT)ですが、対応する仮引数は、
GLboolean 型(8BIT)となっています。
overload resolution で、best matching アルゴリズムで最適な関数を探す際、対象の関数のプロトタイプ宣言の仮引数の型と
実引数の型を比較して、1つでも型が不適格のものが見つかった場合、「viable function」ではないとみなされ、候補から除外されます。
例として、unsigned char 型の仮引数に、int 型の変数を渡そうとすれば、不適格に成り、その関数は対象から除外されます。
しかし、この場合の様に、0 や 1 という整定値ならどうなるでしょうか。つまり、
unsigend char 型の仮引数に int 型の整数であるところの 0 という整数リテラルが、「適合」するというのは、
正しい仕様でしょうか?
その関数はCの関数なので、そもそもマンぐり返されてないし、より適合するオーバーロード関数の存在なんて考慮してないんじゃね?
>>94
> unsigned char 型の仮引数に、int 型の変数を渡そうとすれば、不適格に成り、その関数は対象から除外されます。
これが誤解なのでは?
暗黙変換されるでしょ。 >>96
確認しました。charの仮引数の場所に、int 変数を実引数にして渡しても、
エラーも警告も出ませんでした。
関数呼び出しだけでなく、
int i = 0x123456;
char c = i;
としてもエラーも警告も出ませんでした。
テストは、VS2019のC++で行いました。 整数型同士はどの組み合わせでも暗黙の型変換はされるんじゃね。
変換後の型が符号付きかつ、変換後の型が表現できる範囲に収まらない値だったときの挙動が未定義ではあるので、
狭い方向への変換のときに警告くらいは出してくれることもあるみたいだが、
オーバーロードの解決の際に排除されることはない。
>>98
ついでに、お聞きしたいのですが、
class CBase {・・・};
class CDerived : public CBase {・・・};
の場合、
CDerive* ---> CBase*
への変換は標準変換は有りますが、
CBase* ---> CDerive*
への変換は標準変換は有りませんよね。
しかし、
CBase *pBase;
に対して、
(CDerived*)pBase
というcastは、down castであり、気をつけなければならないキャストではありますが、組み込みのcastとして、
どのコンパイラでもサポートしています。
(この場合、型の解釈の変更だけでなく、マシン語レベルでの生の値も、offset分だけ変更になることがあるのは
周知の通りです。)
ということは、標準変換ではないにも関わらず、キャストではなぜかサポートしていると言うことになるのでしょうか? >>97
viable function とか言うから規格上の確認がしたいのかと思ってたけど、そこは実験でいいのか。 >>100
draftを見たら、実引数から仮引数への標準変換が有る場合には、暗黙の型変換
となりえて、viable function となり、かつ、標準変換には
char ---> int だけでなく、int ---> char の変換も含まれているらしいことが
分かりましたが、確認のため、VC++ 2019でチェックしてみました。
>>101
やはり、「(型)値」の形式を筆頭とする明示的型変換には、標準変換以外でも
「組み込みの変換(キャスト)」
が有るのかも知れませんね。
これは始めて知りました。 >>102
最後、何が言いたいかと言うと、
『「組み込みの変換」には、「標準変換」には含まれていない変換も含まれている。』
ということです。
CBase*--->CDerived*
は、「標準変換」には含まれていませんが、「組み込みの変換」には含まれているということです。
また、それとは別に、int--->charは、危険を招くことがあるにも関わらず、「標準変換」
に含まれてしまっていると言うことです。 CBase* は CDerived* から変換したものかもしれないから変換可能なのが自然だろう。アップキャストとは違って暗黙にはされないし。
C式のキャストはチェックは継承関係をチェックしないがC++のキャストはするしな。
char と int は cast されてる訳じゃないからな
みなさま、色々と有難うございました。
今回はこれで質問を閉じたいと思います。
回答ありがとうございます
使って人いて安心しました
自分は構造体で間に合ってるからまだタプルの恩恵に与ったことない
読んだままだろ
cbの型が合っていないといっているからcbの型をSIZE_Tにすりゃ良いんでないかい
ほうほう。で、どうやって?
言っとくが私はC言語をポインタで挫折した男だ!!
PSIZE_Tとやらじゃね
main関数の中の
size_t cb;
これを
PSIZE_T cb;
にするだけ?
>>117
ありがとう。
でもエラーが以下に変わっただけでした。
processthreadsapi.h(650): candidate function not viable: no known conversion from 'PSIZE_T *' (aka 'unsigned long *') to 'PSIZE_T' (aka 'unsigned long *') for 4th argument あ、PSIZE_Tじゃなくて、SIZE_Tにしたら行けました!!
大文字小文字の間違いだったってことですか?
とにかくありがとうございました!!
変数やら関数にtemplate指定するのに一々上に記述するのが面倒なんですが、スコープ内で一括指定するみたいな記法ってありますか?
typedef HogeT<Fuga> Piyo;
とかこういうこと?
typedef でも害はないけどusing を使うのがモダンな方法やぞ。
C と共用するヘッダファイル (または C++11 未満の規格に従わざるを得ない場合) を除いては typedef を使う理由はもう無い。
template<typename foo>
foo bar[256];
template<typename foo>
foo baz();
を仮に
template<typename foo>{
foo bar[256];
foo baz();
}
みたいな感じで
列挙型を宣言した後に構造体型で列挙型の変数を作成、
列挙型の変数はキーボードから入力できないので、構造体型にキーボードから入力するための変数を作成、
その値によって列挙型の変数に代入、
動的にメモリを確保して列挙型を入力、後に出力
これが上手く動作しないです助けてください
#include<iostream>
using namespace std;
enum Type{Tec, Des, NA};
struct Human{
Type type;
char ans;
};
int n; char* pA;
void dataInput(Type& tp){
for(int i=0;i<n;i++){
cin>>tp.ans;
pA[i]=tp.ans;}
}
void showData(Type& tp);
int main(){
cin>>n;
pA=new char[n];
Type tp;
dataInput(tp);
showData(tp);
return 0;}
void showData(Type& tp){
for(int j=0;j<n;j++){
cout << pA[j] << "\n";}
}
複数のLEDをリズミカルに光らせるプログラムを書いております。
現在は赤、青2色で色々遊んでおります。
'' __delay_ms(100);''
って感じの関数(用語?)を覚えまして、各パート毎に点灯時間、消灯時間を打ち込みました。
で、実行してみた所、1パートの青LEDが全て点滅し終わった後で2パートの赤LEDの
点滅に移る形になってしまいました。
赤、青LEDには各1個づつPICマイコンのピンを振ってありますので
スタティック制御ができるんだと思いますが、その制御(点滅)を同時に開始出来る
文(?)を教えて頂きたいと思います。
よろしくお願いします。
>>129
PICの質問なら電気電子板の方が良いぞ tp.ansで入力された値によって対応した識別子を出力させたいのですが、charでは1文字しか出力できないので手詰まりになってます。どなたかご助言頂けないでしょうか。
>>132 これじゃダメ?
#include <iostream>
#include <string_view>
enum class Type{ Tec, Des, NA };
struct Human{ Type type; }
Type to_type(std::string_view s) noexcept {
if (s == "Tec") : return Type::Tec;
if (s == "Des") : return Type::Des;
// Expects(s == "NA");
return Type::NA;
}
std::string to_string(Type t) {
if (t == Type::Tec) return "Tec";
if (t == Type::Des) return "Des";
return "NA";
}
int main() {
int n; std::cin >> n; // サイズとか要らないので読み飛ばす
std::string str;
std::cin >> str;
auto data = to_type(str); // 列挙型にして保持
std::cout >> to_string(data) >> '\n'; // 文字列型にして出力
} >>133
アドバイスありがとうございますm(_ _)m
ごめんなさい!_が何かは理解できましたが、autoが難解でよくわかりませんでした... mainのスレッドをCPUハグなしに無限に一時停止しておく方法はありますか?
>>136
目いっぱいsleep_forしてループで回す >>136
無限に実行されるサブスレッドの終了を待つ。 mainからWinMainを呼ぶことも可能
WinMainが動いてる間はmainは止まってるよ
強制的に一時停止させるならPauseキー
cmakelistsでメモリ関連の設定の仕方をご教授いただけないでしょうか。
linuxでvswprint()使ってみたんだが、事前に必要なバッファサイズがわからない場合の求め方がわからん。
1. vsnprintf() と同じように nullptr を渡してみた
⇒必要サイズじゃなくてエラーの-1が返ってきた
2. 仮のサイズで呼び出して領域不足のエラーなら増やす方針にした
⇒エラーが領域不足なのか他のエラーなのか見分けがつかない(errno=0のまま)
どうすりゃいいんだろう?
cppreferenceにはエラーが消えるまで再確保&呼び出しやり直す必要があるかもねって書いてある
C++のコードを拾ってきてコンパイルしたら、構造体の初期化で non-trivial designated
initializers not supported というエラーになってしまいます。
例えば typedef struct _Hoge { int a; int b; int c; } Hoge; みたいなときに
Hoge hoge = { .b = 1, .c = 2, }; みたいにメンバーが省略されていると駄目のようです。
でも元のプロジェクトではコンパイルできてるっぽいです。
自分の側では諸般の事情(?)でg++ 7.5.0で-std=c++1zでコンパイルしています。
上記のエラーを避けるにはどういう方法があるでしょうか?
>>148
C++ の規格としてその書き方が採用されたのは C++20 から。
(余談だが C だと C99 から出来る。)
それらの規格に準拠したコンパイラ (より新しいバージョンの g++) を用意するか、
でなければ古いスタイルの書き方で初期化するしかないという普通のことしか言えぬ。 >>149
どうもです。いえ、何かコンパイラーオプションとかあるのかなと思いまして。
ちなみに新しい書き方の場合
1. 全ての要素を
2. 宣言と同じ要素順序で初期化
しないといけない、で正解ですかね? 1.の縛りは未初期化要素を避けるため?
とりあえず Hoge hoge; hoge.b = 1; とか書き直して逃げておこうかと思います。 >>147
ありがとう。なるほど、代替手段が無いとも書いてあるね。
formatにエラーがある場合はどこかで打ち切らなきゃならないか。 >>150
> 1. 全ての要素を
いいえ。 要素の初期化を一部省略して書いた場合は
デフォルトメンバ初期化子 (があればそれ) で初期化するか
あたかも {} が与えられたかのようになります。
つまり >>148 の例でいえばデータメンバ a は 0 で初期化される
ことが保証されます。
> 2. 宣言と同じ要素順序で初期化
はい。 その通りです。
どうしてこのような制限を入れたのかきちんと議論をみたわけではありませんが、
コンストラクタのメンバ初期化子リストは自由な順序で書けるが
実際の初期化順序は宣言の順序になるというルールが微妙にイケてなかったことの
反省なんじゃないかなと想像します。 gdb で、カレントディレクトリに .gdbinit を作って "b func" を記述したんですが、
funcが共有ライブラリの中にあると、funcがまだロードされてないので無視されますよね?
対話的に追加する場合はyを押して強制追加できますが、.gdbinit の中だとデフォでnが
選ばれるようです。.gdbinit の中での強制(自動)追加は可能でしょうか?
ちなみに ~/.gdbinit で add-auto-load-safe-path というのはやってあります。
ググったらありそうですが見つけられず... お願いします。
「C++には特にこれ!と言えるような入門書がない」という書き込みを見たのですが、そうだとしたらC++を習得した人は初学者のときどうやって技術を身につけていったのでしょうか?
「ロベールのC++入門講座(ロベール著)」と「明解C++入門編(柴田望洋著)」を買ったけどこれでいいのかな…
>>154
絶対確実というようなものは挙げられないけど、ほどほどのものはたくさんあるよ。 1. 既に C を覚えて使いこなしてた
2. Eiffel を学んだ
3. C++ は better than C として使った
4. template を学んだ
5. Perl を学んだ
6. Python を学んだ
7. D を学んだ
8. C# 悪くないね
>>155
C++ の規格はちょくちょく改定されてて、特に 2011 年の改定はインパクトが強かったんだ。
入門の範囲にすらいくらかの影響がある程度には。
それより古い本だと (今となっては) 不格好なスタイルになっているかもしれない。 >>156
なるほど
ほどほどのもので学んでいった感じですかね
>>158
参考になります!
ありがとうございます >>158
私は、もう年を取ってもう新しい規格にはついていけないと悟ったので、せめて初心者のための本を買ってレビューする余生を過ごそうと思っています
そういえば江添本を放置してましたね、10/4 の資格試験が終わったら、あらためて江添本をレビューするつもりです 今読んでいる入門書の例題です
時間計算機で9時45分の1時間25分後を計算するには以下のように入力します
945+125=
11:10
http://codepad.org/jOsbQgsX
ところが実行してみるとVC++では0:10、mingwでは0:70という結果が出ます
掲載されたソースと見比べても違いはないようなのでお手上げです
教えて下さい >>161
addclockとsubclockにリターン値がないよ
return hour * 100 + minute;
が必要なんじゃないの? あと、なんて本?
関数の戻り値型(関数名の前に書くintとかそういうやつ)を省略する入門書なんて珍しいから気になる
関数の返却値の型を省略すると int とみなされるのは C89 では保証された動作だったが C99 で廃止された。
だから古い本ならそれほど珍しいわけではない。
そんなに古い本をいまどき手にしてしまうってのはめずらしくはあるが。
>>162
おっしゃるとおりでした、なぜかreturnの行を完全に打ち忘れました。
見直しの最中にも気づかず・・・
今読んでいるのは「はじめて読むC言語」という1991年の本で名著らしいです。
ネットで「はじめて読む8086」の後に続けて読めば理解が深まると言われ手に入れて読んでいます。
途中コンパイルが通らずさんざん頭を捻って拡張子をcppからcにしたら動くようになったりして
古い本で勉強するのはなかなか大変です。
ありがとうございました。 >>165
当時としては名著だったかもしれんが、仕様の改定はあるし、
周辺事情も変わっていくものなので古い資料で入門するのはだいぶん遠回りな気はするぞ。
C は最新規格でも歴史的事情を色々と引きずっているので古い規格から追っていくのも
無駄になるわけではないし、それを楽しめているならそれもよいけれど、
入門の段階で変な苦労を背負いこんで挫折するともったいないので
キツいと思ったら他の学び方もとれるということは覚えておいて欲しい。 いやいや
.cpp を .c と間違えてコンパイル通らないってのは
古い本のせいじゃないぞ
あるあるだけど
世の中にはJavaとJavascript一緒にしてるひともいるからなー(棒)
今の本が終わったらK&Rも読もうと思っていたのですが
VS2019環境だと警告まみれになりそうで気が重くなってきました
俺的には絶版だけどダイテル本がすげー勉強になった
問題までキッチリ解いたらかなりの力になると思う
んで詳説Cポインタでポインタをもっと掘り下げて
今は色々プログラミングしながら(つっても長くて2千行程度)もっとシステムコール勉強してるとこ
それ終わったらネットワークプログラミングもやるつもり
プログラミング言語C 第2版、K & R、1988
C89/90 の本だから古いけど、MISRA-C などの組み込みでは使う規格
>>174
C99 は、C++ への互換性を無視するという規格委員会の独善が鼻につき推奨できない
C89 = K&R2 こそ必要にして十分というべきだろう 原理主義者は読む
というか、原理主義者になりたいので読む
なんつったって聖典だからね
>>175
ほう! 実に興味深い!
具体的に互換性が無視されているというのはどこのことかな? 読むのは勝手だけど
昔の仕様を頑なに守り続けるのもどうかと思う
だからと言って新しい仕様が何でも良い訳ではないが
K&R読むと、コンパイラ作るの楽になるように設計してるなーってわかるよね。
あと、こりゃ別にlintいるわーってのもわかる。
>>178
私のコメントに興味を持ってくれて嬉しい
しかし、今、リアルの私は終わりのない忙しさで連日睡眠時間が 3 時間という有様だ…
おそらく 11月1日2日3日の連休までにはこの忙しさも収束するだろうから、それまで気長に待っていてくれ給へ >>181
PASCAL と C を一緒にしてはいけない
PASCAL は LL(1)パーサですべてが記述されている、という C にはない独自の美しさを誇っている
C はセマンティクスに妥協しまくっておりシンタックスはボロボロだ、こんなものは私の求める美しさではない
高みを目指すのなら、C/C++ の「なあなあですませる」態度に決別するべき >>182
それは大変ですね。
便所にラクガキする時間をぜひ永眠もとい睡眠に使ってください! struct {
char x;
struct {
char a : 4;
union {
char b : 2;
char c : 2;
};
char d : 2
};
};
こうやるとabcdは正常なんですがxの値がおかしくなります
xの最初4ビットがa
xの最後2ビットがd
xの残り2ビットがbとcで共有
どうやればできますか?
>>185
x も union に入れるといいかもしれない。
「xの残り2ビットがbとcで共有」については、間に union 挟む形だと
ビットフィールドの割り付けが途切れちゃうから、 struct {a, b, d} と strunct {a, c, d} に
分ける必要があるかもしれない。
でもこんなことやりたくなるのはハードウェアレジスタの操作やバイナリフォーマットの操作ぐらいな気がして、
そうなると残念ながらビットフィールドや union 使った方法には移植性に難があるのであまりお勧めできない。 >>186
185じゃないけど、レジスタ設定でおすすめのやりかた教えてください。
ハードウェアありきでレジスタ構造再現するより、目的や意味で分類するソフトありきの方が読みやすいように思えたんですが
このやりかたの利点てなんだろう。処理が早い? ポインタって*pは指し示したアドレスの先の値なのに
宣言のときに初期化するとchar *p=xxxx;はアドレスが入るって整合性取れてないなと思ってたら
char* p=xxxx;って意味なのね
>>187
符号なし整数型にビットシフトとビットマスクで。
移植性を考慮する必要が無いなら、出力コード見ながら調整したビットフィールドで望みの動作に
できることも多くて、できてしまえばレジスタの定義も楽でレジスタアクセスするコードも読みやすいから、
それで済ませたくなる気持ちはわかる。
「目的や意味で分類する」というのはレジスタアクセスするコードの上に関数を作る話になると思うので、
レジスタアクセスの方法(ビットフィールドかシフト&マスクかなど)に関わらず好きに関数作って読みやすくすればいい。 >>186
> 間に union 挟む形だとビットフィールドの割り付けが途切れちゃう
納得しましたありがとう! >>188
そうだけど、宣言の文法上の結合規則では * は p の側に結合する。
宣言は char という型指定子と *p という宣言子から成り立っているのであって、
しかし char* という型の p が宣言されるので整合性という意味では
やっぱりなんだか微妙という感はちょっとある。 もちろん慣れたら問題無い
char a[] = "A\n";
char *p = a;
*p = 'B';
char *q;
q = a;
printf("%s", q);
>>191
VS2019がchar *p;をchar* p;に勝手に変更するので
おかしいなと思ってたんだけど知ってみれば納得できるというか >>192
ポインタ難しい論の実際ってポインタより配列、文字列のせいって気がする。 char *p; か char* p; かでごねてる人って
char *p[]; とか char (*p)[N]; とかはどうしてるんだろ
>>195
どっちでもいいけどどっちかには揃えたくない? 自分で揃えりゃいい話だし
他人がどう書こうが関係ないし
vsならvsに任せる
人間がやったらミスするんだから機械に任せる
vs標準のフォーマットが嫌なら変えればいいが、変えた時点で標準ではないと認識しといて
>>197
自分ではどう書くかは決めてるってことなんだよね? ソースの一部が入ると書き込めないな
何が琴線に触れてるんだろ
#define LIST { \
{ "a", "b", "c" }, \
{ "aa", "bb", "cc" },
}
char *(list[][3]) = LIST;
これは便利
1. char *p;
2. char* p;
自分は(1)派だけど
(2)を許すとしたら
3. char* p[];
(3)とか気持ち悪くない?
4. char(*p) [8];
(4)とかは?
破綻してるよね?
()を半角で書くと書き込めない?
普通に半角で書いてるよ
>>202とか()()()とか char(*p) [8];
合わせ技がダメなんかな
>>204
*の位置よりも、小分けに何度もレスするのが気持ち悪い。まとめて1回で書いてくれ。 好きにすればいいじゃない。
世の中的にはCは右、C++は混在が多いんじゃね。
C++なら生配列の使用はなるべく避けるし。
>>203-205
ワイは C++ では char* p; と書く派 (C では char *p と書く派) やけど char* p[]; とは書かんな。
ごく単純な char *p; の場合に限って char* p; の方がマシな気がするという話であって、
全体としてはもうどうにもならんほどグダグダやと思うておる。 >>217
結局、複合型とかconst修飾とか出てくると破綻するんだよね。だから右派。
たまに頑固な左派が「そんな変なものは使わない」とか言うけど、だったら*も止めてスマポだけ使ってろとw char* p, *q;
ってなるやんって思うから右派
意味的にchar* p, q;がpもqもchar*型になるなら左
char *p 派の人は p を const にしたいときは char *const p になるの?
>>221
右派にも親米と反米の二種類がありまして‥‥ 左派の破綻誤魔化しのために
typedef が廃止されて using とか本末転倒過ぎる
#include<stdio.h>
void main()
{
int a = 9;
double b = 2.3;
printf("%d", a + b);
}
これを実行すると-1717986918になるんですがおかしくないですか
%fだと想定通りになりましたが%dのときは11が出るんじゃないかと思うんですけど
a + bはdouble型
%fはdouble型を出力する書式だから意図通りに表示される
一方%dはint型を出力する書式だからそこにdoubleを突っ込むとおかしな表示になる
%dで正しく表示したければ次のようにa+bを明示的にintに変換する必要がある
printf("%d", (int)(a+b));
>>225
丁寧な説明ありがとうございます
%dにしても勝手に整数にはしてくれないんですね、なんか不便な気が。
それにしてもマイナスはどこから出てきたのやら 9+2.3=11.3
これの double の bit 表現が
int だと敢えて勘違いして観ると
MSB 1 で負の数になるんだろ
%dなのに引数がdoubleなら今どきのコンパイラなら警告出すはず
見てないだけだろ
#include <stdio.h>
typedef union {
unsigned char u[8];
double d;
int i;
} U;
int main(void)
{
U x;
x.d = 11.3;
printf("%f\n", x.d);
printf("%d\n", x.i);
for(int i = 0; i < 8; ++i) printf(" %02x", x.u[i]);
return 0;
}
/*
11.300000
-1717986918
9a 99 99 99 99 99 26 40
https://ideone.com/SNupdr
*/ ちなみに
-1717986918
は 32bit int で
0x9999999a
つまり
big endian - little endian で byte 順が入れ替わって
さらに 8 byte -> 4 byte で切られてる
謎解き、魔法を見せられたような鮮やかさでありました
平たく言うと、その%dはこのfloatやdoubleのビットの並びを無理矢理整数にしてしまう
つまり、書いた通りにしか動かない
忖度やお察しが起こって無いのが良いところ
これが不便だと思うなら便利な言語を使うと良いよ
便利ってことは高機能ってことで、高機能ってことは裏でいろんな処理が走る必要があるってこと
そんな処理走ってほしくない環境があるから今でもCが現役なだけ
このばあい言語でなくライブラリの仕組みね
中で(int)vする指定子が用意されてればいいだけ
C++を使ってシューティングゲームを作ろうとしているものです。
https://bituse.info/game/shot/
こちらのサイトを参考にしてDXライブラリも使って作業をしているのですが
https://bituse.info/game/shot/5
ただいまこちらの章でエラーが出てしまい行き詰っています。
背景を線画する章なのですがサイトの指示通りに新しいクラスを作って実行すると
1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------
1>back.cpp
1>C:\Users\rikua\source\repos\gamegame\back.h(17,7): error C3861: 'LoadGraph': 識別子が見つかりませんでした
1>C:\Users\rikua\source\repos\gamegame\back.h(19,10): error C2065: 'MARGIN': 定義されていない識別子です。
1>C:\Users\rikua\source\repos\gamegame\back.h(23,22): error C2065: 'FALSE': 定義されていない識別子です。
1>C:\Users\rikua\source\repos\gamegame\back.h(23,2): error C3861: 'DrawGraph': 識別子が見つかりませんでした
1>control.cpp
1>main.cpp
1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
このようなエラーが出てしまいます。
こちらが現在作成しているファイルの全てです。
http://whitecats.dip.jp/up/download/1603336402/attach/1603336402.zip
パスワード1234
どなたか分かる方お願いします・・ すまん
398MBとか見てそっ閉じしたわ・・・
各ヘッダが何をincludeしてるのか構造見てみて
他人だけど1234で削除したら削除出来ちゃったωωω
>>242
申し訳ありません!
ヘッダは今全部で5つありまして
back.h
control.h
define.h
pch.h
player.h
の5つです
back.h
includeなし
control.h
include "player.h"
include "back.h"
define.h
include <windows.h>
pch.h
include "DxLib.h"
include "define.h"
player.h
#include "pch.h"
#include "player.h"
それぞれは今このような形になっています 最後の
#include "pch.h"
#include "player.h"
こちらの#は貼るときに消し忘れなので気にしないでください
>>244
back.hにpch.hを追加で
player.hのplayer.hはいらない
でやってみて hoge.hファイルに#include "hoge.h"ってできたんか・・・
>>248
帰宅したらすぐに試してみます!ありがとうございます!! >>249
コンパイルエラー選手権でそんなんあったな >>248
すみません!
player.hの内容は元々includeが一つもありませんでした!
なのでback.hにpch.hを追加して実行してみると
このようなエラーが出てきました
1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------
1>back.cpp
1>control.cpp
1>C:\Users\rikua\source\repos\gamegame\define.h(16,13): error C2011: 'SHOT': 'struct' 型の再定義
1>C:\Users\rikua\source\repos\gamegame\define.h(16): message : 'SHOT' の宣言を確認してください
1>main.cpp
1>C:\Users\rikua\source\repos\gamegame\define.h(16,13): error C2011: 'SHOT': 'struct' 型の再定義
1>C:\Users\rikua\source\repos\gamegame\define.h(16): message : 'SHOT' の宣言を確認してください
1>player.cpp
1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== >>252
すみません先ほどのエラーは
違ったものでした
こちらが現在出ているエラーです
>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------
1>back.cpp
1>control.cpp
1>main.cpp
1>pch.cpp
1>player.cpp
1>control.obj : error LNK2005: "public: void __thiscall BACK::All(void)" (?All@BACK@@QAEXXZ) は既に back.obj で定義されています。
1>control.obj : error LNK2005: "private: void __thiscall BACK::Draw(void)" (?Draw@BACK@@AAEXXZ) は既に back.obj で定義されています。
1>control.obj : error LNK2005: "public: __thiscall BACK::BACK(void)" (??0BACK@@QAE@XZ) は既に back.obj で定義されています。
1>main.obj : error LNK2005: "public: void __thiscall BACK::All(void)" (?All@BACK@@QAEXXZ) は既に back.obj で定義されています。
1>main.obj : error LNK2005: "private: void __thiscall BACK::Draw(void)" (?Draw@BACK@@AAEXXZ) は既に back.obj で定義されています。
1>main.obj : error LNK2005: "public: __thiscall BACK::BACK(void)" (??0BACK@@QAE@XZ) は既に back.obj で定義されています。
1>main.obj : error LNK2005: "public: void __thiscall PLAYER::All(void)" (?All@PLAYER@@QAEXXZ) は既に control.obj で定義されています。
1>player.obj : error LNK2005: "public: void __thiscall PLAYER::All(void)" (?All@PLAYER@@QAEXXZ) は既に control.obj で定義されています。
1>C:\Users\rikua\source\repos\gamegame\Release\gamegame.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。
1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== >>252
エラーが出る度に頭空っぽのまま教えてくださいって繰り返すのか?
teratailで指摘されてる通り、まずは#includeとかヘッダファイルがどういうもので何のためにあるのか、何故エラーになるのか、解決するにはどうするか、入門サイトなり入門書なりで勉強してきなよ。
それで分からないことが出てきたら、またここで具体的な質問をすれば誰かが回答してくれると思うぞ。 たびたびすみません!
control.hの中にお手本にはない同じ文列が2つあったので一つ消すと
エラーがだいぶ減りました!
1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------
1>control.cpp
1>C:\Users\rikua\source\repos\gamegame\control.cpp(11,1): error C2600: 'CONTROL::~CONTROL': コンパイラで生成された特殊メンバー関数を定義できません (クラスで最初に宣言されなければなりません)
1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
>>254
ありがとうございます!
もう少し勉強してみてまた質問したいと思います。 ヘッダのインクルード順に依存するようなプログラムになってるとか?
C言語、C++の基本のヘッダファイルの役割は理解していますか?
もし判らないのであれば、そちらの勉強を先にした方がいいと思います。
参考にしているサイトも、
> このページで学習するには、
> C言語とC++についての知識がある程度必要になります。
> 心配な方はトップページなどから、該当言語のページを選んで基礎を学んできてください。
と前置きがありますよ。
基本を理解せずに始めても、何度も同じような質問を繰り返して遠回りになるだけです。
>>246
有賀豚 >>253 の原因は
player.c の中に back.c の中身がそのままコピーで繰り返されてるから >>257
それ以前の問題
こんなソース描いてる香具師が同じプロジェクトに居たら殴る 引っかかってるところよりずっと前で理解してないパターンは面倒くさい。
前提部分からの説明が必要だがそれを学ぶ気がないからこそこういう質問になるわけで、
親切に答えても徒労に終わるパターンなのが見えてる。
Java から C++ に流れてきた者ですが、Javaのインターフェース的なものは
多重継承で実現、ですかね?
class Rectangle : pubilc Polygon {...}; みたいなクラス(他にも Polygon を拡張した
Triangle とか Hexagon とかあるとします)で面積を返す area() の実装を要請して、
そういうオブジェクトだけに適用できるメソッドを定義したい場合、
class Area { virtual int area() = 0; }
class Rectangle : public Sharpe, public Area { int area(); ..}; 的な?
その後 doSomething(Area& area); といった呼び出しでこれらのオブジェクトを引数に?
この場合 Polygon に area() を追加する手もありますが、Polygon でない図形のクラス
でも area() の実装を要請する場合もあるならば、多重継承ということになるのかなと。
多重継承以外でも何かありますでしょうか。
>>263
仮想関数は動的ポリモーフィズムのためにある。
(最適化で消えることもあるけど) 実行時にディスパッチする仕組みなので、
使わないで済むならその方がいい。
つまり、その例なら doSomething をテンプレートにして型に制約 (メタ関数かコンセプトで) を付ける方が好ましい。 >>262
>学ぶ気がない
>親切に答えても徒労に終わる
触っちゃいけない質問者って臭いで判るよな いきなりどこかのサイトのソース持ってきてコンパイルできません系が怖い
オンラインゲームとかでも初心者狩りとかしてそうw
学ぶ気がないとか他人に原因を押し付けてるけど
じゃあこのスレでインクルードやら宣言やらの仕組みから解説しろってのかい?
それはさすがに入門書のひとつでも読んでくれなきゃ困るよ。
単純に説明の分量的にもね。
別にインじゃねえの
答えたくなきゃ答えなきゃいいだけだし
マジでそれ
答えたくないならスルーすればいいのに余計な事を言うのが害悪
>>264
テンプレートですか、C++っぽいですね。メタ関数とか、いろいろ自分には新しいトピックが。
area() を実装しているかどうかは... is_callable とかでしょうか。
最悪制約をつけなくても area() がなければコンパイル時にテンプレート展開でエラーに
なって、駄目なことはわかることはわかるんですよね?
>>265
それはルートクラスの設計の話に見えるのですが、今回の場合はもう既に
あるクラスの場合の話でして。その場合はインターフェースクラスを多重継承する
のかな? というのが元の質問です。 >>272
まあ仮想関数使って多重継承でいいんじゃね
機能的には必要十分かと
それより設計上の問題として
Polygon : public Area{}
という構造が適切なのかどうなのか疑問
分かりやすさとしては
Rectangle : public Polygon{},Triangle: public Polygon{}・・・
という単なる形状のみの継承クラスと
Graph {Polygon poly; int area();・・・}
という別の目的で機能するクラスに分けたほうが整理されてる気がする >>272
制約を付けなくてもテンプレートを展開してダメだったらエラーになることは保証される。
まあ当たり前っていうかそうせざるを得ないもんね。
でも「(制約を満たさないので) マッチに失敗した」と「マッチして展開した結果にエラーがあった」は意味が違っていて、
結果的に失敗させることを意図するならなるべく前者で失敗させた方が使い勝手はいい。 答えたくなきゃ答えなきゃいいし
余計な事を言いたきゃ言えばいいよ
ここをどこだと思ってんだよw
>>276
は? 学ぶ気がないことが露骨なやつは嫌だよねって話をしてるんだろうが。
初心者叩きとか話をすり替えるなよカス >>276
初心者で一括りにしたら「やる気のある」初心者に失礼 こいつには質問しても得るものないから目合わせないでおこう
と思うやつに限ってこういう反応してくるんだよなw
>>277 >>277
>学ぶ気がないことが露骨なやつ
ほんとこれにつきる リンカーの話とかもここでおkですか? とりあえずlinux系で、
動的ライブラリlibA.soが、別のライブラりlibB.soに依存しているときには,
libA.so作成時、libA.soにlibB.soをリンクしておけば依存性が解決されますよね?
(libA.soを使うプログラム作成時には、libA.soだけ指定すればよい)
諸般の事情で静的ライブラリlibC.aがあり、これがlibD.soに依存するのですが、
この場合、libC.aにlibD.soをリンクしてlibC.aを生成することはできない? ですか?
libD.soは、libC.aを使ったプログラムの作成時にリンク、ということでおkですかね?
これが正解だと、静的と動的で依存性を解決する場所(?)が違うんだなあと。
ふと思いましたが、前者の場合、libA.soにあえてlibB.soをリンクしないで生成、
プログラムにlibA.soをリンクするときにlibB.soを指定する方法もありますよね。
そうすると依存性的には静的ライブラリと同じになる。
でも普通はあえてそんなリンクにはしないのかな。
virtual int d(){cout<<"Ad\n";}
にreturn文ないのが未定義動作でその時の振る舞いはコンパイラの実装依存なのかな
virtual int d(){cout<<"Ad\n";return 0;}
で正常に動いた
ていうかなんでこの手のコンパイルが通るようになってるんだろうね
そっちが気になるわ
http://codepad.org/qCDIHh55
の件で
delete b; は B:d, ~B, A:d, ~A と呼ばれる様ですが
virtual int d() はポリモフィズムで
B:d, ~B, B:d, ~A と呼ばれるのが正しい気がするのですが
デストラクタ内から呼ばれるときは特別なのでしょうか? >>282
libD.aはないですw libD.soです。
なんというか、静的リンクって面倒だっなって思ったのと、自分の認識が正しいかを
確認したかったのですが。
プログラムにlibA.soをリンクするときは、libA.soだけ指定すればいい。llibB.soの依存性は
リンカーが解決してくれる(libA.soにlibB.soがリンクされているので)。
一方プログラムにlibC.aをリンクするときは、libD.soも指定しないとlibD.so内の関数が
見つからないエラーになる。かといってlibA.soのように依存するライブラリーを前もって
リンクしておくわけにはいかない。
で正しいですよね? ~B の後 ポリモフィズムで実体のない B:d() を呼び出すのは微妙な感じ
B:d() 内部で Bにまつわるメンバを操作を考えると
すでに生命期間切れてるのにアクセスすることにもなる
>>290
コンストラクタ、デストラクタ内では仮想関数はオーバーライド解決されない、ポリモーフィズムは効かないとはっきり決まっておる。 >>290
抽象クラスを端的に言えば「実行時の型 (実装) で処理する」ための仕組みなのであって、
delete b; は *b の型が B のつもりで解体するってだけ。 ~B::B()の内部で~A::A()が呼び出しされてるだけだから
B::d() -> B::~B() -> A::d() -> A::~A()
で正しいんじゃないの~A::A()を普通に呼び出して
B::d()が呼ばれたら怖くない?
いくつかのクラス (A, B, C) をまとめて class X に対して friend にしたいとき
class X 内で
friend A, B, C;
と描くとエラーになります
friend A;
friend B;
friend C;
と描くしかないですか?
あと前方参照のために
class A, B, C;
みたいに並べるのもだめっぽいのですが
他に良い描きかたあるんですか?
なぜ後者を良くない書き方だと思った?
その書き方で良いじゃん
僕は友達いないのですがfriend 0(;´Д⊂)と書くべきでしょうか?
>>302
あなたが誰かを勝手にfriendと宣言しても問題ありません。
ただ相手があなたにアクセスしないだけなので、現状と何ら変化はありません。 こんなこといいな出来たらいいな
#define A(X, Y, ...) X Y ; A(X, __VA_ARGS__)
A(class, hoge, fuga, hage)
A(friend, hoge, fuga, hage)
>>305
念のため言っとくけど俺はhageじゃないからな 友達がいないからハゲなのか
ハゲだから友達がいないのか
>>305
一応出来るよ
トークン連結でA_30,A_29とかあらかじめ作っといたループ部分を呼べば、だけど 下記のようにvectorに追加するときにemplace_backを使って初期値を入れるにはどうすればよいでしょうか?
typedef struct aaa_{
char name; // charもしくはstd::stringでも可
uint64_t count;
} aaa;
std::vector<aaa> v_aaa;
char temp[] = "hoge";
// v_aaaの末尾に初期値を入れて追加。イメージ
v_aaa.emplace_back( aaa({name=temp, count=5}) )
無理じゃね?
structにコンストラクタを用意する訳にはいかんの?
暗黙のコピーコンストラクタか…
emplace_backの意味ねー
引数を受け取るところでも RVO の適用対象になるから余計なコピーはたぶんそんなに起こらないはずだと思う。
(ちゃんと検証してないので間違ってたらごめん。)
>>315
ありがとうございます。できました。
高速化のためにemplace_backを使っているのですが、もしかすると逆に余計なCOPYが発生している可能性もあるんですね。 もう一つ質問です。
uint16_t num;
std::string str;
という2つの変数があった時、strを数値変換してnumに入れたいのですが、下記はどちらも間違ってはないですか?
どちらも戻り値はintとあったのですが、uint16で受けても問題ないのでしょうか?
num = std::stoi(str);
num = atoi(str.c_str());
問題があるかどうかはstrの仕様次第
uint16_tの範囲外があり得ないなら大丈夫、あり得るなら勿論ダメ
今時のコンパイラなら大きいものから小さいものへの暗黙の変換には警告が出る
警告消したいなら明示castして
>>320
int から uint16_t の変換について
変換後の型で表せない範囲の値を変換しようとしたとき、変換後の型が符号なし整数型である場合には、
変換後の型が格納可能な最大値 + 1 で modulo を取った値になることになってる。
(変換後の型が符号付である場合には未定義。)
結果の大きさが確実に uint16_t の範囲に入るという確信がある状況であればもちろん問題ないし、
そうでないときも結果が未定義ではないという意味では問題ないが、
プログラムの意図に合致するかどうかは状況による。
----
文字列を数値に変換することについて、
atoi はエラーハンドリングがちゃんとできない (変換に失敗したら 0 を返すが変換結果が 0 のときと区別できない) ので、
事前に文字列の検証が済んでいるのでなければ stoi の方が好ましくはある。 >>322
>変換後の型で表せない範囲の値を変換しようとしたとき、変換後の型が符号なし整数型である場合には、
>変換後の型が格納可能な最大値 + 1 で modulo を取った値になることになってる。
>(変換後の型が符号付である場合には未定義。)
結果的にそうなってるだけで実際は上位bit(byte)棄ててるだけじゃないの >>324
結果的にそうならないと規格準拠はうたえないし上位を無視してやるかどうかは実装の話だから処理系による
まあ他にいい方法は思いつかないけど >>324
言語仕様で保証されている。
その仕様を実現するためにコンパイラがどうやるかは場合によるだろうけど、
単に上位を捨てることで実現しやすいと想定はしてると思う。 >>325
1 の補数を使っているときにマイナスの値が絡んでくるとちょっと調整が必要になるんじゃね? stoiとか" -1"とか食わせると-1のintになるんでしょ
parserとかゴリゴリ実装してんのかね
>>328
扱えるのは整数だけだし、マイナスの他には 0 か 0x が付く場合を処理できればいいのでそんなに複雑ではないと思う。 https://ideone.com/o3N4x1
上記の44行目の「ここから〜」と70行目の「ここまで」の部分で変数p_aaa、p_bbbのstr変数を書き換えるという同等の処理をしているのですが、
実際のここの部分は何十行もあるので、メンテナンス性を良くするために、この共通部分を共有できないかと考えています。
関数化すればと思いましたが、引数の構造体が別物のため関数化できません。
何か方法はありますでしょうか? unsigned char* common(unsigned char* arg)
{
送信しちゃった
unsigned char* を受けて realloc し、 reallocの戻りの [9][10][11] を書き込みしつつ
reallocの戻りを返す (失敗は exit) そういう関数 common() で
p_aaa->str = common(p_aaa->str);
p_bbb->str = common(p_bbb->str);
こうまとめる感じ
ideone のコードがあくまで str の操作に終始してるので >>333 になる
共通のコードが type についても同じ操作するのなら
str, type だけを単発の構造体 BASE にして AAA, BBB は BASE を継承しておく
で、関数は BASE を受ける(必要なら BASE を返す or 参照渡しで書き換え) offsetofで距離の値をメタ取得しメンバアクセスでなく剥いでchar*にすればいいと思うよ
>>334
関数にp_aaa->strを渡して値の書き換えを考えたのですが、関数内のreallocでアドレス変わるからその値を変えてもだめだ。
って思っていました。
ご提案の通りアドレス変わったものを戻り値で返してあげればいいですね。
その考えが抜けていました。
>>335
すみません、剥いでchar*にすればいいってところがよくわかりませんでした。。
>>336
今回以外のケースでも使いみちありそうなのでテンプレートについて調べてみました。
関数やclassを定義する先頭に<typename T, typename HOGE>のように可変できる独自の型を作れる。
関数、クラス使用時に関数名のあとに<unsigned char*, int>のように型を指定する。
という理解であってますか? こんな感じで定義したいときどうすればいい?
template <X>
class X {
public:
X() {}
~X() {}
};
>>341
それで定義したとして、どのように使えるものが出来上がればいいの? >>342
template <class X>
class A {
X *x;
public:
A(X *a) : x(a) {}
~A(){}
};
int x = 1;
A<int> a(&x);
A<A> b(new A<int>(&x)); ←ここエラー
こういうときに
class A {
A *x;
public:
A(A *a) : x(a) {}
~A(){}
};
みたいな A とよく似た B C D ... があるとき
template <class X>
class X {
X *x;
public:
X(X *a) : x(a) {}
~X(){}
};
って描けると便利かなと思いました >>343
その説明を見てもイマイチ要求がわからんのやが……。
全く同じ内容で別の型にしたいということなら幽霊型 (phantom type) を使うという手法はあるけど。 >>343
> A<A> b(new A<int>(&x)); ←ここエラー
その記述(特に A<A> という型)でどんな結果を期待していたのかわからない。
> みたいな A とよく似た B C D ... があるとき
A と B は何が違うのか(なぜ A ひとつではダメなのか)わからない。 >>345
>その記述(特に A<A> という型)でどんな結果を期待していたのかわからない。
class A {
A *x;
public:
A(A *a) : x(a) {}
~A(){}
};
です
>A と B は何が違うのか(なぜ A ひとつではダメなのか)わからない。
上の例だと最小限にしたつもりなので差が無くなってしまってますが
実際は template <class X, class Y> みたいにして Y が違う感じです 幼女が身振り手振り一生懸命しつもんしてると思うと萌えてくるな
>>346
ごめんさっぱり見えてこないや。「最小限にしたつもり」で情報削りすぎてるんだろうな。
質問の基本として、望む結果、そのために書いたコード、実際の(望ましくない)結果、あたりはそろえてもらわないと
うまくお話しできない。 >>340
ありがとうございます。勉強になりました。
ついでに追加で質問があります。
最初に投稿したコード →https://ideone.com/o3N4x1
の36〜37行目で値と0x00を入れるのに2行使ってますが、これ以上簡素化はできないですよね?
36: memcpy(p_bbb->str, bbb_str_temp, 9);
37: p_bbb->str[9] = 0x00;
あと54〜56行では3行に分けて1バイトづつセットしてますが、ここを一気に入れる方法はありませんか?
イメージは21行目のcharを初期化するときのように {0x41, 0x41, 0x00} みたいな書き方ができないかなと思っているのですが。
54: p_aaa->str[9] = 0x41;
55: p_aaa->str[10] = 0x41;
56: p_aaa->str[11] = 0x00; >>346が言ってるのは多分、テンプレート引数によって異なる識別子のクラスを定義したいってことじゃね?
それは型の次元じゃなくて識別子の次元だからプリプロセッサでやるしかないと思うが と思ったけどよく読むとなんか違うっぽいな・・すまん
>>351
charにキャストして書き込みですか。なるほどですね。
ありがとうございます。 c++14のconstexpr変数について質問です
constexpr変数は内部リンケージですので、グローバル定数をconstexpr変数で作ろうとすると複数の翻訳単位で実態が作成されてしまうと思います
c++17ではinline変数とすることでただ一つの実態を指すようにできますが、c++14ではどのようにすればよいのでしょうか?
コンパイラがよしなにしてくれますか?
static constexpr
で後は良きに計らってもらえ。
>>357
サンプルコードありがとうございます。
引数を可変で受け取ることができるんですね。
これ色んなところで使えそうですが、ぱっと見た感じちょっとクセがあって難しいですね。
思考が追いつかない。。
じっくり考えて理解してみます。 float a = 1.234;
float b = 1.234f;
double c = 1.234;
double d = 1.234f;
これらの違いを教えてください
double に 1.234f を使って float に 1.234 を使うのが正しいんでしょうか?
>>359
何も付けなければ整数リテラルはint 小数リテラルははdoubleとなる。
つまり
float a = 1.234; doubleをfloatに変換して代入
float b = 1.234f; floatをfloatに代入
double c = 1.234; doubleをdoubleに代入
double d = 1.234f; floatをdoubleに変換して代入
でfloatの値を指定したい時だけfを付ける。 ありがとうございます
float a = 1.234;
これで警告が出ないのは不思議ですね
以下のコンストラクタの書き方は正しいのでしょうか?
Duration(int data) : data_(data), negative_(false) { // メンバ初期化
if (data < 0) { // 条件を満たすとき上書き
data_ *= -1;
negative_ = true;
}
}
>>365 まずどこが正しくないと思ってるのか言えよ。 Duration(int data)
: data_{data < 0 ? -data : data}
, negative_{data < 0} {}
と書けるのを発見しました。お目汚し失礼しました。
下記のようにfor文の外で構造体を参照できるようにするにはどうすればよいですか?
newで生成するとmallocのように寿命が無いオブジェクトを生成できるとネットで見たのですが、そうなりませんでした。。
std::unordered_map<std::string, XXX*> unmap;
for(){
xxx = new XXX ←構造体
map["key"] = xxx; ←構造体のポインタを代入
}
map["key"] ←for文の外でxxxを参照できるようにしたい。
変数名を間違えてるところがあったので訂正します。
std::unordered_map<std::string, XXX*> unmap;
for(){
xxx = new XXX ←構造体
unmap[key] = xxx; ←構造体のポインタを代入
}
unmap[key] ←for文の外でxxxを参照できるようにしたい。
>>368-369
書かれたコードを見る限り参照はできそうなので、何を見て参照できないと言っているのかがわからない。 >>370
そうなんですね。
もうちょっと複雑な条件があるのかな。。
ちなみに変数unmapはclassのpublicで定義していますがそれは関係ないですかね。 あと、newで構造体を生成したときにdelete関数を使わずに勝手に消えてしまうケースなどはないでしょうか?
そもそも何かの勘違いか間違いでfor文のループに入ってないとエスパーしてみる
>>373
ありがとうございます。参照できてますね。
となると別の問題のようです。
for文内でprintf()すると出力されるのでループ内には入ってるようなのですが。。
どこかで変なことをやらかしてるんだと思います。
すみません、ちょっと考え方を変えようと思います。
>>373 の下記で変数mを定義していますが、このmから m.***() のようにしてXXXを生成できないでしょうか?
これであればmが生きている限りXXXは残ると思うので。
std::unordered_map<std::string, XXX*> m; イメージは下記のようなものです。
これで作成したXXXはfor文を抜けても生きているのでこの方法なら解決するかなと思いました。
std::vector<XXX> xxx_vector;
xxx.vector.emplace_back();
XXX* xxx = xxx.back();
変なことしなくてもnewしたものはdeleteするまで生きてる
そこじゃないとこがbugってるだけ
普通にbugを潰せ
理解しないままで偶然に動くまで弄るってのは悪い手癖になるぞ。
newの戻り値はブロック内だけ有効って思ってるとか?
何が変なのかさっぱり
>>377
forのあとで
XXX* xxx = m["0"];
をすればmからXXXを取り出せるけど
そういうことでもなく? すみません、色々調べていたら思いっきり勘違いしていました。
結論としてはnewできちんと保持されていて、
>>373 のコードで言うと、XXX.cの値を設定し忘れていて、forを抜けたあとでXXX.cを見て何もセットされてない!ってなってました。
この修正をすることになったきっかけが、最初
xxx = new XXX;
ではなく
struct XXX xxx;
でやったり、forを抜ける前とあとで
printf(%p\n");
でポインタが変わったり、とかを調査していてそれらとごっちゃになり、newでやっても消えてしまう。
と思い込んでいました。
newに修正したときもちゃんとポインタで調べればよかったのですが、xxx.cの値で確認していたため起きた勘違いでした。
お騒がせしてすみませんでした。 >>382
次からは問題をちゃんと再現できるコードを作って相談しなよ。
そうすればその手の勘違いには自分で気付ける。 >>382
プログラム書く前に最低でも入門書読むなり入門サイト見るなりして
基本的知識は持ってないとでたらめコード量産するだけ
お前向いてない
過去にも同じような指摘どっかでされてないか? みんな似たようなことを通ってきてると思うけどね忘れてるだけで
実務で書いてるコードで問題あって
そこから問題が再現するエッセンスとなる最小部分を抽出してテストしてみるかー
抽出の過程でポカ発見は割とある
(最適化無しだと期待通り動いて最適化maxにするとセグフォしやがるタイプの追跡が辛い)
>>385
失敗や勘違いは誰にでもあるし
そのことは否定していない 最初の最初はセーブデータとかもexeファイルの後ろの方に付け足す感じなのかと思ってた
atan2(y, x) を多項式近似で高速化しようとしたけど
場合分けが多くて結局遠回りしてるような気がする
本当に高速化出来たんだろうか
標準ライブラリもテイラー展開で実装されているだろうから、相当小さい次数で打ち切らないと太刀打ちできないと思われ。
入力される値が有限個なら予め計算しておくのも手。
いずれにしても先に計測だね
必要とする精度によるけど予め飛び飛びに計算しといて間は線形補間とかした方がいいかも
どうしても高速化が必要なら、あらかじめ値域を限定して情報量減らすなりしかないよな。
線形補間で必要精度が達成できる最小限のテーブル実装…て数学か。
floatもdoubleも使わずに
atan2iみたいなの造れば速いかな
qiitaで聴かれてもいないのに発表ですね判ります
readで回すケースがあるのか?…僕は…C++なので…std::ifstreamのgetlineで一行づつやるので…
う”ーん…1回でいいんだけど…これ…どうなんでしょうねぇ…。
結局…1行分のバッファをINとOUT両方取って…回しました…SJIS→UTF-8だとOUTのバッファが足りなくなるので…
回したら…いい感じにできた…。余分にバッファ取らなくてもいい…これがいいね…。
文字列終端の'/0'…ヌル文字…改行コードの\rや\nや\r\nって…文字コードによって…バイト数って変わってくるの?
変わるんだったら…非常に面倒なんだけど…。特に…'/0'は…長さを測れない…。誰か…。
'\0'用に配列のBUFFERは多めに取るか…\rや\nや\r\nは…findで切ろう…。面倒だ…。
改行コードは簡単だけど…char配列の最後の'\0'意外に理解に苦しむ…。
2バイトになるケースがあるのかと…。
かなりショックだね…これじゃ…辛い…UTF-16のLinuxの場合に問題が出てくるのか…。
UTF-8端末であれば…'\0'で問題ないだろうね…。UTF-16のLinuxってある?
この話の流れだと…UTF-16のLinuxはぶっ壊れるよね…。
僕は…C++なので…文字列は使いたくないだろうね…。
文字処理なんか相当面倒&複雑な割に得られるメリットが少ないので手を出すこと自体が間違い
外部ライブラリに頼るべき典型例
悲惨だ…文字「A」…UTF-16で文字コード「0x0041」を…iconvすると…EINVAL…これもナル文字の影響なのか…。
ちょっと…今日は…ショックを隠しきれない…C++に挑戦してるが…引退が頭をかすめる…。
とりあえず…海外のStackOverFlowで聞いてみようか…。
ライブラリのバージョンが違うのかもしれないiconvctlで制御できそう…。
今使ってるのは…iconvctlがない…。明日は…そのあたりの環境構築から…。
char使えるのはマルチバイト文字だけだぞ
UTF-16や32使うならwchar_tかchat16_tとかchar32_t使え
WHATWG、Encoding仕様は、注意深く実装すればプッシュ型に出来るぞ。
プッシュ型の設計は、柔軟な利用法を可能とする。
弱点は、キャッシュに乗りにくく関数呼び出しが増え、実行効率が落ちること。
とはいえ、そろそろプッシュ型の時代が来ても良いのではないか?と思う。
なぜなら、Enter押した瞬間に実行が終わるから。
独り言やめてください
・このコードをコンパイル実行し(ようとし)ました
・結果こうなることを期待していました
・実際にはこうなりました
こんな感じでお願いします
Enter押した瞬間に実行が終わるとはどういうことかわかるか?
ときどき、あれ?いま押す前に結果が表示されたよな??と思うときがあるって事ですよ。
そのくらい速いって事ですよ。
最近のパソコンは。
近頃のRuby on Rails の未経験者なんて、10年やってるプログラマーよりも、レベルが高いぞ。
ポートフォリオに学校で作った、Twitter・メルカリクローンとか
AWS, Linux, Docker, Rails, CircleCI, Terraform, Chef, Itamae とか
C++の入門書を一通り終わらせました。
次にCUDAでのGPU処理を勉強しようと思います。
試しに行列演算するclassを作ったのですが
classのoperatorをCUDAで処理って出来ないのですか?
できないことないでしょ。
でも必要になるまで結果を取得しないfutureみたいなオブジェクトを返却するほうが良さげな気がする
>>429
もともとビットシフトの演算子だったが、標準ライブラリなんかで、
std::cout << ”こんにちわ、仕事" << std::endl;
みたいな使い方がされて、それに倣って、データを流し込むという
意味合いでこの演算子がよく使われる。
送信バッファーの末尾にどんどんデータを追記してるんだろうが、
これはライブラリ製作者が決めたことだ。
こういった元の演算子から大きく意味を変える演算子の再定義は
悪しとする批判的な意見もある。他人が読むことガン無視で
俺様仕様に調教していくのも趣味的で否定はせんけど。 >>430>>431
ありがとうございます。
このような演算子でオーバーロードされたデータをUDP経由で受け取って各データを取り出す場合、どのようにして取り出すのでしょうか?
左から何バイトずつ取り出して変数に格納するみたいなことをやる感じになるのでしょうか? >>432
演算子のオーバーロードとそのクラス内でどのようにデータが保持されているかは直接の関係はない。
クラスのデザインによる。
よう知らんけど >>429 の URL を踏んでも 404 なんやが。 >>433
すみません、UnrealEngineのコードは、GitHubのアカウントとUnrealEngineのアカウントと紐づけないと404になるようです。
紐づけ自体は無料です。
該当箇所のコードは以下のようになっています。ちょっと全体をキャプチャするのは難しいですが...
>>434
その SendBuffer とやらがどう定義されているかによるので
使われている箇所だけを見てもわからんという話をしてる。
この場合はバッファと名前が付いてるから蓄積はされるんだろうけど、
たとえばネットを抽象化したクラスだったら
すぐさま送信してしまって手元にはデータは残ってないみたいなことだってあるかもしれない。 SendBufferを含む行は以下のようになっています。
これが定義になっているのかは分かりません…
const uint8 BLEND_SHAPE_PACKET_VER = 6;
// FrameTime BlendShapeCount Blendshapes SubjectName DeviceID
const uint32 MAX_BLEND_SHAPE_PACKET_SIZE = sizeof(BLEND_SHAPE_PACKET_VER) + sizeof(FQualifiedFrameTime) + sizeof(uint8) + (sizeof(float) * (uint64)EARFaceBlendShape::MAX) + (sizeof(TCHAR) * 256) + (sizeof(TCHAR) * 256);
const uint32 MIN_BLEND_SHAPE_PACKET_SIZE = sizeof(BLEND_SHAPE_PACKET_VER) + sizeof(FQualifiedFrameTime) + sizeof(uint8) + (sizeof(float) * (uint64)EARFaceBlendShape::MAX) + sizeof(TCHAR) + sizeof(TCHAR);
FAppleARKitLiveLinkRemotePublisher::FAppleARKitLiveLinkRemotePublisher(const FString& InRemoteIp) :
RemoteIp(InRemoteIp),
SendSocket(nullptr),
SendBuffer(MAX_BLEND_SHAPE_PACKET_SIZE)
{
}
FAppleARKitLiveLinkRemotePublisher::FAppleARKitLiveLinkRemotePublisher() :
SendSocket(nullptr),
SendBuffer(MAX_BLEND_SHAPE_PACKET_SIZE)
{
}
>>436
それは FAppleARKitLiveLinkRemotePublisher のコンストラクタの定義。
FAppleARKitLiveLinkRemotePublisher 型のコンストラクタは
データメンバの SendBuffer を MAX_BLEND_SHAPE_PACKET_SIZE で初期化するという意味。
ようするに SendBuffer が何者かはわからん。
> これが定義になっているのかは分かりません
さすがにそれはあまりにも基礎知識すぎてそこから解説する気にはならないな。
どうして入門書を読むことすら一切せずにいきなり質問に突入するのかわからん。 >>437
そうですね…
定義になっていないだろうなとは思ったんですが、これ以外にSendBuffer変数がどこにも見当たらなかったので
もしかしてこれで定義になってるのか…?という疑問の余地があったからそう書いてしまいました
Unrealのコード全体から調べてみると、TArray<uint8> SendBuffer;というのがあったりするので、もしかしてこれかなと思ったりするのですが、違う可能性は高そうです…。
そもそもUnrealの質問をC++のスレで聞くのが間違っていたかもしれないですが、Unrealのスレでもあまりプログラミングの話題は出ないので…
勉強して出直してきます…
ありがとうございました! >>429
多分SendBufferに突っ込まれてるデータを横取りしたいんだろうけど、
SendBufferに<<で突っ込まれてるデータを一つ一つ自分が用意した配列とかに保存すりゃ出来ると思うが
UEが受信したデータを取り出して使いたいのなら、それはSendじゃないとおも 2D-arrayを初期化する際、
arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
とすべき所を、ついPythonの癖で間違えて
arr[][3] = {(1, 2, 3), (4, 5, 6), (7, 8, 9)};
と書いても、g++でコンパイルは通ってしまいます。当然、値はメチャクチャです。
C/C++ で、配列初期化の中に()を書くと、コンパイラーは何だと思って解釈してるのでしょうか?
>>390
cスレで言うのもなんだけど、ループで総和計算にcは全く向いてないよ
pc上のgccでさえ、ccとfortranで10-100倍の差がある(-O1で比較)
cからの呼び出しオーバーヘッドも一回なんで気にする必要はない
再帰でたらい回しするようなコードは値渡しのcに多少分がある C++にも,pythonのsympyやnumpyのようなライブラリってあるのでしょうか?基本,自作しなければならないのでしょうか
>>446
おお!参考になります!
当方,ずっとpythonを使ってたんですが,ちょっと処理が重くなりそうなツールを作ってみたくなり,c++に興味持ち始めました
文法理解以外に,ちょっとした数式計算やグラフ化に手こずる予感がしていたのですが,eigen3使えばなんとかなりそうな気がしてきた次第です struct A{const int a; A(const int a):a(a){} };
struct B{ A as[4]; B(const int a):####{}};
上記####の部分は文法的にどのように書くべきでしょうか?
as({a,a,a,a})
みたいに書きたいのですがGNU拡張がどうの言われました
as{a,a,a,a}
で通りました(C++11)
お騒がせしました
>>444
PythonNN.dll 経由すれば C++ からも numpy sympy 使い放題 class Hoge; があるとして
Hoge *funcA()
{
return new Hoge;
}
Hoge funcB()
{
Hoge hoge;
return hoge;
}
Hoge &funcC()
{
Hoge hoge;
return hoge;
}
Hoge funcD()
{
Hoge *hoge = new Hoge;
return *hoge;
}
の違いって何ですか?
戻り値のインスタンスがなんなのか考えれば判るんじゃね
ちょっと疑問に思ったんだけど、PythonはC/C++の10倍速くないのか?
処理系やライブラリがC系で作られてるのだからそれはない
まあバリバリ最適化、場合によってはfortranとかも使ってたりもするから下手な組み方より速かったりするかも知れないが
たいていの言語はC/C++比何倍速いと言うのを売り文句にしてるけどな。
Javaは20倍速いという有名なベンチマークがあったな。
>>451
funcA: 呼び出し元で delete しないとメモリリーク
funcB: あまり問題ない
funcC: 戻り値にアクセスすると未定義動作
funcD: 呼び出すたびにメモリリーク
new の負荷や Hoge のコピーの負荷が気になったり気にならなかったりするかもしれない。 倍速い プログラミング
で検索して見たら、一等賞はRubyだった。
日本人として誇らしい。
プログラムが速いのとプログラミングが早いのは別やろ
>>458
funcBってコピーコンストラクタが呼ばれる?
効率悪くない? funcCのやったら駄目コード funcDの確実に漏れるコード
と比較すると些細に見える
>462
保証はないけど、コンパイラが頑張ってくれる場合があるんじゃなかったっけね?
>>451 >>464
Hogeのデストラクタでリソース解放するようなパターンで
2回解放されると困る場合があるな
もちろんブロックしてあったとしても解放一回でも問題ある訳だが 未定義動作はどういう処理されるかわからないので所詮メモリリークするだけとわかっているfuncDのほうが些細に見える
大抵の環境でこの手の未定義でメモリリークよりひどい状態にならないので、そういう環境であるならfuncCのほうが些細であると言える
>>466
debug中は動作するけどrelease版にすると落ちるとか 馬鹿がCのCGIモジュールで地方自治体のサービスを書いたせいでメモリリークしまくりの
複雑怪奇なコードが多量にある。対処が高価でメモリー潤沢なマシン、アホアホ大手のN
歴史的経緯で仕方がなかったんじゃないの?
全部作り直しますからお金くださいなんて提案はなかなか通らないからね
CGIの場合、確保したメモリーを解放しないのは、十分妥当な戦略なので、メモリーリークではないかもしれない。
高価なマシンは、アクセス数の対価では?
さっと実行してそのまま終わるコマンドラインツールなんかだと
メモリの free はしなくて良いという論はあるね。
つっても、プログラムは改修されることもあるし、
一部を部品として切り出して転用したいこともある。
駄目だったらまた最初から作り直せばいいじゃんと言えるような
規模でもない限りはやっぱりそれなりに作法に
則っておかないとグダグダになると思うんだよな。
記憶域確保のコストは議論されるのに、なぜか解放のコストは議論されない。
>>474
何を言ってるんだ? されてるだろ?
だから最後の free をすべきかどうかとかいう論が出てくるんじゃないか。 >>450
こういうのもあるんですね
ぜひ参考にさせていただきます! Hoge funcB2()
{
return Hoge{};
}
C++17以降はこれが正解
他に対してデメリットしかない
move constructor と copy constructor があるのは理解したが
どちらがどういうタイミング(条件)で使い分けられるのか
詳しく正しく解説してるサイトはありませんか?
>>481
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。 rvalue を受け取れるところに rvalue を渡したらムーブになるという単純な規則なので詳しい説明を見るまでもないよ。
(一定の条件を満たすとコピーもムーブも省略して直接オブジェクトを構築するといったような例外はある。 いわゆる RVO)
でも何が rvalue なのかとか右辺値参照の仕組みだとかいった前提知識は必要なので、
そこらへんも含めた総合的な説明となると「江添亮の C++ 入門」を一通り読めばいいと思う。
https://ezoeryou.github.io/cpp-intro/ string Hoge(){ return string("HOGE"); } があって
string s = Hoge();
char *p = s.c_str();
で p を使用する側があるとき
const char *Fuga(){ return string("HOGE").c_str(); } を代わりに使おうとすると
const char *q = Fuga();
までは正常(に観える)ですがその後 q の中身が消えてしまいます。
理由は判るのですが Fuga みたいな関数を作りたいときどのように描くのが普通ですか?
>>486
最初の3行で書いているやり方でいいんじゃないの 例を満たすだけなら
const char* Fugo() { return "HOGE"; }
が一番楽だと思うけど、もうちょっとやりたいことを具体的に
ふと思ったのですが、
文字の配列(文字列)を char * で表すとき、最後の要素をヌル文字にすることで、文字列の長さを
別に指定しなくて済んでますよね。
同様に、任意のデータ(例えば構造体とか)の配列をポインタで表すとき、終端に何か特別な
値をセットして、配列の要素数を指定せずに済ませられますかね?
番兵値とかnullオブジェクトパターンとかでググれ
番兵を知らないってことはアルゴリズムの教科書を買った方がいい
ただのnull終端を番兵と呼んでるんなら、
それこそまともなアルゴリズムの本をちゃんと読んだほうがいい。
strlen()はあるのにobjlen()とかlistlen()とかstructlen()が無いね
listはお決まりのイディオムで
sizeof(list)/sizeof(list[0])
配列をポインタで関数に渡すとき、番兵を使ってる例って少ない(無い?)ですよね?
たいていはポインタと、サイズの入った変数、ですよね。
番兵を使った方が関数の引数が減ってシンプルじゃないですかね?
sizeof()は上記目的には使えないですよね。あと配列をmallocで割り当てた場合も。
そもそもC++スレなんだからコンテナでrange based forとかイテレータとかsize使ってるやつの方が多いんじゃねーの
番兵はユニークな値でないと困るけど
一般の配列で絶対に使わない値 が存在しうるかはわからない
文字列は \0 を番兵として使うからなと値域を制限してるから成立してる
>>497
番兵の値がいくつかということはコメントとかに書くくらいしかできないからサイズを使う場合よりも保守性が低いとか、サイズが分からないと直接終端にアクセスする必要のあるアルゴリズムを使う際にいったん末尾まで余計な探索しないといけないとか、デメリットも多いな。ケースバイケースだが、番兵よりサイズの方が扱いやすいことが多いと思う。 >>497
自分は、C++でよく見る先頭ポインタと末尾+1ポインタのペアが落ち着く。 >>497
ポインタの配列とかならまれに見るよ
Win32APIのStartServiceCtrlDispatcherAとか
逆に言うとポインタぐらいしか番兵としてみんなが認める値がない
ポインタならNULLを番兵にするのはだいたい同意するだろうし Go や Rust でスライスが基本的な型として入っているのは
大きさのわからん配列 (の参照) が
問題を生みやすいことを学んだ故だと思う。
C++20 に std::span が入ったのもその必要性・有用性を認めてのことだろうから、
std::span そのものは使えない状況であったとしても
番兵より大きさ (もしくは終端の位置) で管理するスタイルが基本になっていく流れはあるんじゃないかな。
たとえばある配列をわたされてインデクスiを参照したいとするじゃん
番兵しかなかったら、とりあえずインデクスiまでずーっと舐めないと
途中で番兵でてきたらアウトオブレンジでえらいこっちゃ
配列とサイズで管理しないとランダムアクセスがごっつうおそなってお話にならない
で、まあ実際ヌル終端文字列の処理ってこんなのばっかりで、文字列をやたらと
きったりはったりする場合は結局文字数とセットにしたほうがいいよね、ってなって
最近のモダン言語はだいたい文字数とセットで管理するほうが主流だよね
C言語に前にあったPascalとかも知らないんだろうな…
最近のモダン言語は文字数とバイト数がバラバラだけどランダムアクセスできてんの?
>>508
文字列をランダムアクセスする必要とかあるの?
ないよね?
っていうのがモダン言語の解じゃないかな。
どうしても必要なら事前に 32 ビット整数 (に相当する文字型) の配列にするし。 >>500
char * なのに
"hoge\0fuga\0hage\0\0"
みたいな内容期待してるAPIとかあるからな >>497
malloc とか new とか
ポインタ - 1 のアドレスにサイズが書き込まれてたりするな C++17のvariantというものを初めて使おうとしていますが
自分のコードでは、variantの中身にはすべてset(int i)というメソッド(iの値をセットする)があるので
visit([=](auto& v) { v.set(hoge); }, value);
としたら、「const ...をset()のthisに渡すのはクオリファイアーを無視してる...」的なエラーに。
あれ、自分の元のコードではvalueはconstじゃないはずなんですが....
もしかしてvisit()の変数って強制的にconst扱いですか? constじゃないやり方とかあります?
>>512
きっと省略したところに問題があるんでしょう。
オンラインコンパイラにエラーを再現させるコードを貼って示してもらえば、何か見えてくると思います。 ヌル文字は文字列処理してセパレータが被った時の最終手段なので勘弁して欲しい
>>497
そういう時、自分は構造体に配列のポインタとサイズを書き込んで、構造体のポインタを渡している。
実務経験ゼロのアラフィフ日曜プログラマなので、この方法が良いのかどうかはしらない。
理工学部出身なので、学生時代はプログラムしてたよ。
コロナ禍で外出する頻度も減ったので、久々にプログラミングを再開してみた。 >>515
あ、実は既にその方法にしていたりします。
配列のポインタ+サイズの引数だと若干うるさくなることのほかに、構造体でデータ型をネストしたい
(構造体の要素に配列を持たせ、その配列の要素も似たような構造体...)部分などもあり、そうするのが
自然(というか必須?)な感じがしました。 C標準ライブラリのソースコードを眺めていると、実装した関数をエイリアスで別名をつけていることがあります
C言語のことがよくわかっていない為か、最初からエイリアスの名前で関数を書いた方がいいのではないか?と思えてしまいます
一体、なんのために実装関数名とエイリアス名を分けているのですか?
昔の6文字までしか名前を解決できないボロリンカの名残だろ
初心者だけど目的がないから勉強できん
どうすればええんや
>>515-516
APIだとそもそも構造体の先頭数byteにその構造体のサイズが入ってるって普通 Visual C++のアプリ作れって言われたんやけど
アプリ作成の段階でワイ詰んだから質問しに来たンゴ
アホみたいな初心者やけど助けてほしいンゴ
【使用環境】
Visual Studio 2008
【やりたいこと】
VB.netとかで言う「Buttun1_Click」で
「MessageBox.Show("HELLO")」がやりたい
【わからないこと】
@本とかで「Managed C++ アプリケーション」で作れって書いてあるが
テンプレートにそんなものはない
A「Dialog」をなんか作れることはできたが
ビルドしたら「error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。」
が出てくる。
定義すれば解決!らしいけど定義のやり方がわかんない
Bmain関数をどこに書けばいいかわからない(ファイルが多すぎて)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
本を使う場合はその本のバージョンに全部合わせないと無い項目とかあってしんどいよ
慣れれば無くなってても代わりはこれだろ、って当たりつけられることもあるけど
学習目的で参考する本があるならバージョンは合わせたほうがいい
そのバージョンの入手が難しくなっている場合もあるからその場合は本を変えるしか無い
出版された後にバージョンが変わってしまいそのとおりに学習ができないというケースが多発するので本よりググったほうが楽という面が大きい
環境たる Visual Studio の使い方が バージョンで全然違うからねぇ
それを使えた上で 何かの言語とAPIやフレームワーク駆使して実行ファイルを作るから
ド頭でつまずくと先進むのは難しくなるわな
個人的には前例になっとるプログラム(機能は違うが、処理内容はほぼ同じ)
がVC++で作られとったからそれを参考にしようと思ったんやが
何せプログラムではなく「プロジェクトの作成」で詰んでしまってなあ・・・
まさに「何していいかわからん」状態ですわ・・・
>>522
Windows の GUI アプリのエントリーポイントは (main ではなく) WinMain なので、
スタートアップルーチンは WinMain があるものだと思って呼び出そうとする。
それがないからエラーって言ってる。
WinMain がどういうものかはここに公式な説明がある。
https://docs.microsoft.com/ja-jp/windows/win32/api/winbase/nf-winbase-winmain
それと他の人も書いてるが Managed C++ はやめたほうがいい。
.NET Framework を基盤にするアプリケーションを書くときにネイティブコードとの間で仲立ちする
のが主な目的のもので、普通のアプリケーションをそれで書くのは適してないし、
仲立ち用に使うにしても今では C++/CLI のほうがマシというのが一般的な評価だと思う。
俺自身は使ったことないから聞きかじりの評判しか知らんけど。
>>528
Windows のデスクトップアプリを一から書くなら C# のほうが楽だと思うから
C# スレへ行けと言いたいところなんだが、下手に前例があるのはしんどいな……。 処理の主体がOSに近い所(GUIで窓の操の面倒をみるのがほとんど)なら
先例をもってくるほうが手近だけど、データ処理ならエッセンスだけ抜き出して
C#でGOするのもアリかもしれん
仕事で言語指定までされてる話ならがんばれ
C++ で、DLL を作るプロジェクトじゃないの?
漏れなら、Ubuntu 18.04, mruby で、C/Ruby ごちゃ混ぜで書くけどw
そもそも、Windows で、C/C++ の仕事があるのか?
想像できない
すべてのサーバーが、Linux なのに
>>533
仕事はサーバーだけではない。
サーバーはLinuxだけではない。 >>528
それ、Managed C++なの?
マジでそうならC++じゃなくてC#にした方がまだマシだぞ このスレにまでRubyキチガイが現れるようになったか
>>522
私ははるか昔に visual c++ にほとほとあきれ返ってしまったので、それいらい cygwin の中にある mingw32 を使って win32api だけを使って書いていた時期がありました
最近は c++11 以降ではスレッドも簡単に書けるようになったので、まあ、しばらくお休みはしてはいるのですが、いつか、c++11 主体で、ときどき win32api を呼ぶ、という感じの混在させたようなものを書いてみようか、などと、鬱々と考えています、考えているだけですけど‥‥ 奥が深いというか複雑なんやなこれ
とりまvs2008なのは会社の環境やから許してくれや
vc++もほとんどいじってなかったしなぁ
あれからとりあえず「空のc++アプリケーション」つくって
「dialog」1つ作って「ボタン」1個置いて
あとは「サブシステム」はちゃんと「windowsアプリケーション」にしたで
ダブルクリックしたらイベント書けるらしいけど
何かいたらいいか分らんかったから
とりあえずMessagebox::show("");
だけ書いた
結局出てきたエラーが
fatal error C1189: #error :
Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version.
Please #define _AFXDLL or do not use /MD[d]
c:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afx.h
なんやけどワイはここで詰んだ
前任者マジでこのツールどうやって使ってたんや・・・?
アホやけどほんま教えてほしいやつこれ
プロジェクトのプロパティで/MD[d]とか書いてあるところを血なまこになって探す
見つかったらそこを/MDに変える
>>538
それ多分.NETじゃなくなってない?
余計遠ざかってるんじゃね 元の司令は >>522 「Visual C++のアプリ作れ」だから正解 Linuxって…テキストファイルの最後には…必ず'\n'が入るって仕様なの?
なんか…GTK系は全部…そんな感じ…。最後に'\n'が入ると想定して最後は改行してない…。
気持ち悪いんだけど…。'\n'なしで終わってもいいよね?…どうしよう仕様合わせようか…
'\n'なしで終わったらいいじゃない…。カルチャーショック…。どう思います?
>>542
やたらと...を使うのに比べたら、最後に¥nが無いことくらい気持ち悪くもなんともない ファイルの最後で改行して終わるってのはコーディング規約とかでも結構あると思うが
C++のイディオムでwhile(std::getline(…, …))ってあるけど、
あれもファイル終端にLF無いと破綻するよ
Vim で勝手に改行を付け加える仕様がどうこうで揉めたことがあったような。
テキストはどことやりとりするかわからんし、
POSIX の中だけで完結できるわけでもないからなぁ。
どっちも想定しておくに越したことは無いよね。
ちなみに C や C++ のソースコードも昔の仕様だと最後が改行ってのは要求されてたよ。
いつ削除されたんだったか覚えてないけど。
>>546
え、マジで?たった今タイプしたとこなんだけど >>549
ごめんうろ覚えでした
元の文字列に改行があったかがeof()でチェックしないと分からなくなる
前にそれでwhile条件節から外してブロック内でbreakしたほうが便利なことがあった……ってだけでしためんご getline や fgets 入力ストリームの最終行が改行を含まずのに閉じられてる場合
バッファの末端に \nが居ないだけで最終行は取り込まれるよね?
そういえば他人のコード変更をレビューするとたまに最終行に改行が追加されているのがあって、
「あーこの人が勝手に改行を追加したのかな、まプログラム的には同じだしいっか」とか思って
無視し続けていたが、あれはその人が使っているエディターによって自動的に変更されてた
のかな?
例えば最初にコードを書いた人のエディターは最終文字が改行でなくても構わなかったが
2番目に直した人のは改行を要求するとか...
clang-format あたりでそこら辺は統一できるのかな?
最近まで、Ruby の1-liner に、バグがあった
末尾の改行コードを削除するために、chomp を使うべき所で、
文字列の末尾の1文字を削除する、chop を使っていた
最終行に改行が無くて、abc なら、ab になっていたw
>>554
getline はデフォルトのデリミタだと ' ' と 改行で切られる (ファイル終端の改行はあってもなくても同じ結果)
また fgets と違って取得した文字列にデリミタは含まれない
ちなみに ifs >> s も getline と似た使い方が出来るが
こっちはデフォルトのデリミタは改行のみ ( ' ' ) は取得される
また取得した文字列にデリミタは含まれない
つまり ifs >> s と getline(ifs, s) は同じではない googleのv8がc++で書かれてるってきいて興味もったんですが最強?
>>561
そういうインフラ用途には C/C++ しかないかと‥‥ v8みたいに飛躍的に処理速度伸びたエンジンって他になにかあるんですか?
すみません、C++で0以上の整数の範囲を表す型を使いたいのですが、どうするのがおすすめですかね?
struct { unsigned begin; unsigned end; }; ま、基本的にこれでいいんですが、もしより良い方法があれば...
- もしかして std::pair の方がいいんですかね? ただの struct よりメリットがあったりします?
- 一応、「有効な範囲を指してない」という状態が明確化できたらいいんですが... 最近 std::optinal というのを
知ったのですが、大げさ? 上記 begin と end を signed にして負のときは無効、とかでもいいんですが。
- 2つの範囲に対して各種集合演算的なものもできるとさらに。
lowerbound+offsetの方が融通が効くのでは
範囲としては倍表せるわけだし
wrap around しても2周はしないわけだから、範囲に入ってるかの判定には問題は無い
>>566
> - 一応、「有効な範囲を指してない」という状態が明確化できたらいいんですが...
end < begin なら有効でないってやればいいだけじゃね? >>566
std::ranges::views::iota 変な質問ですが
std::vector<int, std::allocator<double> > を定義しようとしたら
static_assertでタイプが違うと指摘されました
じゃあなんでテンプレート変数分けてるんですかね...?
自作のアロケータを使う時に使う、
型が違うのはお約束に反する
テンプレートテンプレートパラメータにしなかったのは何故なんだろうな
>>571 そう言われてみれば当たり前の話な気がしますね・・・ ああそうか、Allocatorだけ受け取る方法もあるのか
すみません。C/C++自体というよりは、その学習方法についてですけど、教えて下さい。
ネット上で無料で公開されているC++の学習コンテンツで一番良いもしくは定番のものはどれでしょうか?
私はC, Java, C#の経験があります。しかしながら、Cはほとんど忘れてしまいました。
その状態の人間がC++をネット上の無料のコンテンツのみで学習したいのですが、どのページが良いでしょうか?
開発環境は既に準備しました。
よろしくお願いいたします。
とりあえずwebのロベールとかでも良いとは思うけど・・
独習とかの本は何か持っといた方がいいと思う
ウェブのロベール本ってこれのこと?
http://www7b.biglobe.ne.jp/~robe/cpphtml/
いまどき #include <iostream.h> とか書いてあるのはちょっと微妙だと思うぞ。
どの箇所だったか忘れたけど const の扱いで現行の仕様に合わない部分について
Taratail だったか Qiita だったかで見た記憶もあるし。
個別に見ればささいなことだけど、
入門者はそのささいなこともわかってないから入門者なわけで、
細かい引っ掛かりが多いとしんどいんじゃないか? >>575
本を買った方がいいでしょう、それも複数買う前提で、この世界では「一冊で完結」は無理です
最初の一冊なら私なら旧独習をお勧めします(私がそうでしたから)、が、新独習の評判は聞いてみたいとは思っています >>577
お前がゴリ押ししてる江添本よりはマシだと思うよ >>579
俺は江添本を (全体を通しては) 読んだことがないのでごり押しするほど強い関心無いんだけど。
ただ C++ は C++11 が大きなターニングポイントになってるので、それより古い前提の説明は論外という立場。
ましてや C++03 にすら合致しないのは論外も論外。
論外のものを除いて入門向けにマシそうな、
しかも無料で読めるものというと江添本以外に実質的に選択肢がないからよく挙げるだけだよ。 >>575
話題に上がったから紹介しておくけど、江添本ってのはこれのことね。
https://ezoeryou.github.io/cpp-intro/
入門書であまり取り上げられないけど入門者が躓きがちなコンパイラのコマンドの話や makefile とかいった周辺事情も
取り上げているかわりに、ヘッダファイルを使い分けしなかったり、継承を扱わなかったりで、
網羅的に C++ を理解するための本ではない。 入門者が入門するための本。
それ以上のことは他の本を読めという投げっぱなしだが、
とりあえず無料で基礎をおさえられる (しかも日本語!) という意味では他に紹介できるほどのものはない。
C++ ではありがたいことに無料で利用できるリファレンスは意欲的に整備している方々がいて、
https://ja.cppreference.com/w/
https://cpprefjp.github.io/
あたりを見れば細かいことも書いてるんだけど……。
まあ当たり前だが入門書をひとつも読んでないレベルだとみてもわけわからんと思う。
本気で取り組むなら本の数冊くらいは買ったほうがいいと私も思う。 そら今時コマンドラインツール使っててソース1つだけで書いてるようなC++オタクには合ってるかもしれんけどな・・
他に存在するなら紹介するんだけど、
無料でという制約の中で (個別のブログ記事とかじゃなく) それなりに筋道をつけた入門書で古すぎないものとなると無いだろ。
英語でいいならあったりするかな?
>>581
自分は半月ほど前に最新版の独習を買って、半分ぐらい(p370あたり)読み進めているんだが、「本書について」によると、C++14とC++17をメインのターゲットにしてるって書いてますね アドバイスありがとうございます。
とりあえず、教えていただいたロベールさんのページを見たのですが、網羅的に書かれているようなのでまずはこれを読もうと思います。
> いまどき #include <iostream.h> とか書いてあるのはちょっと微妙だと思うぞ。
すみません。これ、何が悪いのでしょうか。。。
あと、教えていただいて気がついたのですが、C++も結構色々なバージョンがあるのですね。
私が今回触らなければならないコードはかなり前のコードなので、もしかすると古いバージョンのC++かもしれません。
その辺も意識して勉強しなくては駄目ですね。
今はもう標準ライブラリに.hがついてるのは無いからそもそも実行できない可能性ある
>>585
旧独習には「std::stringを自分で実装せよ」という初級者には眩暈がするほどの崇高な課題が採用されていましたが、新独習には「〜を独力で実装せよ」系のお題は採用されていますか?
すくなくとも「〜を独力で実装する」系お題が可能になるだけの基礎知識をつけてくれる本ですか? >>589
全13章605ページのうち7章380ページまで進んでいますが、そのようなお題にはお目にかかっておりませんな。
練習問題やその章の理解度チェックで色々な問題が出されていますが、何れも本をよく読めば解ける問題ばかりです。
さらっと先まで目を通してみましたが、そのような課題は見当たらないようです。
旧版のどの箇所あたりで出題されたものですか? もしかして、全く別の本のことなのでしょうかねえ。
↓の「おまけ」にあるような解答を求める問題でしょうか?
std::stringの実装に学ぶC++入門 - Qiita
https://qiita.com/YSRKEN/items/dd3b11e4670bb2b829a5
自分はまだ独習中で、C++は未だ*や&、&&、で頭の中がグルグル回ってしまうレベルなもので、理解できそうですが
いきなり自力で作れそうにありませんわw >>586
> これ、何が悪いのでしょうか。。。
1998 年に国際規格 (ISO) になって以来、規格に iostream.h というものが有ったことはない。
.h は不要。
諸々の事情から iostream.h も用意している開発環境が多かったせいか
古い書籍では iostream.h としている場合は少なからずあるのだけれど、
主要な処理系の標準への準拠が急速に進んだこともあって、
資料も規格に寄せた書き方が今では普通。
iostream.h は古い本の象徴みたいな感じになってる。
そんでもって規格にない以上は iostream.h が存在しない開発環境も普通にあるってのが問題。
https://wandbox.org/permlink/kwpJf5BumkarYWYD
規格になくてもデファクトスタンダードとしてどこにでもあるってのならまあいいかと思わないでもないけど、
無いこともあるんだ。
そういう環境だともちろんエラーになる。
初心者が入門書の最初に載ってるコードを入力してみてエラーになるってのは良くはないだろ。
そんでもって問題がそれだけとは限らなさそうという……と思わせるサインなんだよ、 iostream.h は……。 >>590
手元の旧独習4版(ハーバード・シルト著)6章末「総合理解度チェック」
・次の演算ができるような strtype クラスを作成しなさい
・+ 演算子による文字列連結
・= 演算子による文字列代入
・<>==による文字列比較
固定長文字列を使ってもかまいません。難問ですが、よく考えていろいろと試してみてください。
必ずできるはずです。 >>590
>C++は未だ*や&、&&、で頭の中がグルグル回ってしまう
これらの「記号」は習得に順序があります。
まず * をしっかり理解します。C/C++ はなんといってもポインタが基本です。
次に参照 & を理解します。参照& を使う場面が出てきたら、これを * を使った書き方に書き直す、という機械的な訓練がいい練習になるでしょう
参照 で返す、という場面でも、@参照返しが出来る場合と、A参照返しはできずせいぜい RVO に期待するしかない場合、の@A二つの違いを明確に即答できるようになるべきでしょう(最近まで私はそれができなかった……)参照& の表現は新しい表現( ranged-for とか) でよく目にしますし、@Aは結構重要だと思います
&& は多分最後でしょうね、私も && は良く分かっておらず、というか、分からないから使わないという態度に留まっていますが、まあそれでもなんとかなる気がします QZ案外初心者やなw
でも言ってることは全面的に賛成
ポインタや参照、クラス等の基本を抑えてからでないとスマポや、C++11からの要素(右辺値参照含む)の使い方もわからんと思う
>>595
>でも言ってることは全面的に賛成
ありがとうございます!
>QZ案外初心者やなw
もう永遠の初心者のままだと思っていますが、それならそれで「初心者の気持ちが分かる視点からの意見の表明」という形でコントリビュートするのもありかな…、と。 個別の機能を理解してからそれの組み立て方を学習するのがまどろっこしく感じる人もいると思う。
抽象度の高いほう (スマートポインタなど) から解体していく形での
学習のアプローチもそれはそれでありかもしれん。
個人的には個別の機能を先に学んだほうがいいとは思うんだけどね。
実例から学ぶと使い方のパターンとして頭に入ってしまって正確な理屈を
きちんと習得できない気がするから。
そうは言っても途中で学習を諦めてしまうようだと正確さもくそもないから、
人によってわかりやすさは違うし学習にはいろんなアプローチがあるということは
覚えておいてほしい。
確かに、私が理解している狭い範囲においても、イテレータが先かポインタが先か、とか
C++11 / std::thread から入門したけど posix-thread なんか知らん!とか
そんな人から補強説が来るのが楽しみです
>>591
ご回答ありがとうございます。
理解しました。
その辺も調査しながらやります。 QZが意外と素直で好印象度アップ
逆に高飛車な餃子の高感度ダウン
Qちゃんは昔からいるけど態度は変わらんね
ときどき自前のコード上げてるあたりは好ましい
プロへのリスペクトは持ってるし謙虚ではある
餃子ちゃんはマジメというか
いちいち規格に沿って発言してくれるんで好ましい
ただコード上げてるのはみたことないんで実力は不明
アマチュアなのにときどき調子乗っちゃってるのも微笑ましい
はちみつのコードたまーに見るけどすごい変な癖があるよ
意味があるなしに関わらず固執するタイプなんだろうな
参照を返す関数の質問です。
オブジェクトの複数のパラメータを設定するときに、obj.param1(...).param2(...).param3(...); みたいに呼ぶ
パターンがあるじゃないですか(ちなみにこれって名前はあります?)
これをやりたいときは
Obj& param1(int val) { mParam1 = val; return *this; }
みたいに参照を返すように宣言しないとダメですよね?
Obj param1(int val) { mParam1 = val; return *this; }
だと、obj.param1(...) は動くけどリターン用にオブジェクトの(余計な)コピーが発生する、
obj.param1(...).param1(...) みたいに呼んだ場合はオブジェクトのコピーに2番目の呼び出しが行われ、
結局破棄されてしまうので、objに2番目のparam1()の呼び出しが反映されない。
こんな理解で正しいでしょうか?
実は参照を使う判断にイマイチ迷っているんですが、もしかして毎回(オブジェクトの宣言、引数、戻り値等)、
「このときはここでオブジェクトのコピーが発生するから...」とかイメージすべきなんですかね?
例えば関数の戻り値、関数を出るときに戻り値が臨時で複製されて呼び出し元に渡されるイメージを持って、
「ああこれだと余計なオブジェクトが生成されるよな、じゃあ参照だ。」的な判断?
obj + a + b + c
operator + () は obj そのものを書き換えず、新たな実体を戻す
obj += a
operator += () は obj そのものを書き換えるついでに、自分自身の参照を戻す
これのどっちに合致したほうが都合がいいかで
複製を戻すか、自分自身の参照を戻すかを分けてる感じ
>>609
その wikipedia の C++ サンプルは int main() が二箇所に現れていますが、これってどう読むのですか? すみません。
仮に、本を買って勉強する場合は独習C++というのがいいのですか?
独習C++はCの知識がなくても大丈夫ですか??
>>610
単に使い方のサンプルを便宜的に main で書いてあるだけでふたつあるのは特に意味ない。 >>605
>これをやりたいときは
>みたいに参照を返すように宣言しないとダメですよね?
>obj.param1(...).param1(...) みたいに呼んだ場合はオブジェクトのコピーに2番目の呼び出しが行われ、
>結局破棄されてしまうので、objに2番目のparam1()の呼び出しが反映されない。
確かに、メソッドチェインを繰り返すたびにコピーコンストラクタが呼び出されるのは、イマイチ、という感覚を私も同様に持ちます
だからメソッドチェインを書くときには私も参照を返すように書きます、結局のところ「参照を返す」というのは「ポインタを返す」ことですから、コンストラクタの走りようがない
しかし「参照を返す『必要がある』」と言い切れるかどうか?
「結局破棄される」というのは最後のメンバ関数が返す実体を回収していないからであり、「参照を返すから」破棄されるわけではないと感じました。
実際、この実体を回収すれば、それはそれで 2 番目以降の呼び出しが意味を持つように書けると思います
https://ideone.com/skVFOr
https://ideone.com/LAKqIj
参照でよくわからなくなったときに私がよくやる「参照返しを全く使わずポインタで押し通す」とすると次のようになるかと思います
https://ideone.com/R82zEE だからムーブコンストラクタとムーブ代入演算子があるんだろうが・・
クラスFooのメンバ関数fの型ってどう書くの?
戻り値void、引数intです。
>>620
f の型は void (int) だけど f へのポインタの型は void (Foo::*)(int) >>621
それはメンバ関数へのポインタでしょ
聞いてるのは関数の型でもなく、メンバ関数の型です C だと関数指示子 (Function Designator) で説明されたりするんだが、
C++ の仕様を Designator で検索しても出てこないな。
シグネチャもまたちょっと違う概念だし、
このあたりのきちんとした解説がまとまったものがあればぜひ読みたい。
「メンバ関数の型」が必要になるケースって何じゃろ?
>>622
だから「f の型は void (int)」って書いたのに、なんでそれが答えじゃないと思うの?
typedef void ftype(int);
struct Foo { ftype f; };
void Foo::f(int) {}
int main() { Foo x; x.f(0); } 関数ポインタを考える以前は関数の型と言えばイコール評価した値の型だったな。
今は関数の型とかもうどうでもよくて
一周回り帰えりキャプチャとかダイナミックスコープとかの有用性や整合性が中心よね
pod的な意味でなく論理的整合性的な型付けの恩恵受けたいなら、別に包む必要無くても常に即席structで返しててやんでい
C++/CLIで、スタティックライブラリからマネージドクラスを公開するのは無理なんでしょうか?
ヘッダファイルに全部実装書けば出来る、ってところまでは調べたんですが、ソースコードをプロジェクト外に置いてるのと変わらないので…。
ダイナミックライブラリでできるならそれでも構わないです。
>>630
.NETでstatic libraryなんて作れたっけ?
最終的に.exeと.dllができるのが邪魔だからstatic libraryにしたいというだけなら、
いったんDLLとして作ってILmergeするのが一般的だと思う >>631
Lib自体は作れるし、アンマネージクラスなら公開もできるんですが、マネージクラスだと参照側でメンバーが参照できず、LNK2020が発生してしまうんですよね。
ビルドオプションでなんとかできるものなのかな、と。 LNK2020ってそれnativeのC++からリンクしようとしてる?
そりゃ無理。その仲立ちをするためにC++/CLIがあるのに。
一応nativeのC++からでも自分でCLRを立ち上げたりしてマネージドクラスにアクセスする方法は
あるらしいが、リンクしてそのまま呼ぶという形にはならない。
自作のプログラム、起動時の読み込み処理の前に以下を入れると
for(int i = 0; i < 100; ++i){
OutputDebugString("dummy!!!!\n");
}
起動時に行っている外部データの読み込みが凄く速くて
これを無くすと凄く遅くなるんですが怖い…
3分くらい違いが出るので明らかにおかしい
どっかでメモリでもぶっ壊れてますかね?
どういう理由が考えられるでしょうか?
さっきのダミーを入れなくても
普通にコードを追加したりしてても遅くなったり速くなったりする
別に読み込み処理の部分とは関係ないところでも。
なんでだろう?
>>637
それは、本当に native の C++?
もしかして、C#のC++/CLI とか? コンパイラはほんと何してるのか分からんから、問題の部分だけ切り出したのを.sへ吐かせて読みなさい
10行程度のcコードなら、edxとか変な名前のは取り敢えず変数だなって思って追えば、アセンブリ知らずとも大体分かるよ
>>635
いや、
C++ライブラリ内にマネージクラスを作って
マネージのC++プロジェクトから
呼び出したいだけ
DLLだったら、C#のDLLからマネージクラスを呼び出すのと
理屈上同じだからできそうな気がするのだけれど
以前実装した時はInterfaceだけ公開して
呼び出されるとそのインスタンスを返す、みたいなことをしたんだけれど >>640
.NETはstatic libraryをサポートしていない
出来上がった.libにはそのマネージドクラスのメタデータとか入ってないんじゃない? >>641
結局そういうことだよね
なんか普通にlibのクラスを呼び出せますみたいなのをサンプル付きで出してた記事があってさ…。
まあstaticメソッドしかないクラスばかりだから、アンマネージクラスで公開するか、namespaceでまとめます。
ありがとうございました。 >>638
C++とWin32APIのプログラムです
>>639
これは自分へのレスですか?
特に遅くなる以外は止まったりする事もないので
困ることはないですがなんか気持ち悪い… >>643
外部データの読み込みは、fopen, _open, CreateFile、CFile のどの系統を使
ってる? >>643
関係ないかもしれないが、HDDが寿命で故障寸前の時にHDDの読み込みが
時々極端に遅くなったりする現象を経験したことがある。
その場合は、そのプログラム以外でも同様の現象が起きるが。 >>645
もし、他のアプリやファイルマネージャーも遅くなることがあるなら、
CrystalDiskInfoなどで診断してみて欲しい。
そのアプリだけ遅くなるが、アプリの動作は正常、というなら、
メモリーやスレッドやOSリソースの使いすぎなども考えられなくは無いが。
何か極端に変わったことしてたりしない? OutPutDegugなんちゃらの関数がファイル出力してるなら、単純にそのドライブのアクセス準備が整ってないとか。
以前、SSDに同じファイル名で一時ファイルの作成と削除を繰り返したら、SSDの仕組み上めっちゃ遅くなったことがある。
>>645-647
遅くなる原因の個所が分かった!
画像を読み込む時にメモリを操作して
16bitで読み込む部分があるんだけど
これを32bitで読み込むようにすると
どんなコードでもまったく遅くならない。
メモリの操作の部分がおかしかったみたい。
自分で書いたコードじゃないのでよくわからない。
32bitのやつと16bitのやつを載せるのでおかしい所あったら教えて。 これは遅くならないコード
int X = 0;
for(int y = ImageHeight - 1; y >= 0; --y){
X = 0;
for(int x = 0; x < ImageWidth; ++x){
pPx[X] = ((DWORD*)pSrcBuf)[x + (y * ImageWidth)];
++X;
}
pPx += Pitch;
}
これが遅くなる場合があるコード
WORD px, tmp;
BYTE b;
int X = 0;
for(int y = ImageHeight - 1; y >= 0; --y){
X = 0;
for(int x = 0; x < ImageWidth; ++x){
px = 0x00000000;
pPx[X] = px;
b = (BYTE)((((DWORD*)pSrcBuf)[x + (y * ImageWidth)] & 0xff000000) >> 24); //A
tmp = 15 * (b / 255.f);
px |= tmp << 12;
b = (BYTE)((((DWORD*)pSrcBuf)[x + (y * ImageWidth)] & 0x00ff0000) >> 16); //R
tmp = 15 * (b / 255.f);
px |= tmp << 8;
b = (BYTE)((((DWORD*)pSrcBuf)[x + (y * ImageWidth)] & 0x0000ff00) >> 8); //G
tmp = 15 * (b / 255.f);
px |= tmp << 4;
b = (BYTE)((((DWORD*)pSrcBuf)[x + (y * ImageWidth)] & 0x000000ff)); //B
tmp = 15 * (b / 255.f);
px |= tmp;
pPx[X] = px;
++X;
}
pPx += Pitch;
}
pPxは、32bitの時はDWORD*で、16bitの時はWORD*になってた。
全て載せると長くなるので変更すると速度が変わる部分だけ載せたよ。
16bitの方でも>>636のダミーを入れれば遅くならないんだよね。
やっぱメモリが壊れてるのかな? >>651
pSrcBuf, pPx, Pitch の型、及び、それらを初期化しているコードが重要。
そこに問題があるとバッファオーバーランしている可能性が捨てきれない。 >>653
「初期化しているコード」を載せる際、ImageWidth, ImageHeightとの
値の関係が分かるようにしてほしい。
要は、ちゃんとバッファの範囲内に読み書きが収まっているかどうかが知りたい。 >>652
例えば、pPxの指しているメモリーブロックのバイトサイズが、
Pitch * ImageHeight * (pPx の 1 要素当りのバイト数)
以上に、pSrcBufの指しているメモリーブロックのバイトサイズが、
ImageWidth * ImageHeight * 4
以上になっていることが重要。 そういえば、pSrcBufを((DWORD *)pSrcBuf)のようにキャストしてから使っている
ことも気になる。
pSrcBuf = new DWORD [ImageWidth * ImageHeight]
ではなく、
pSrcBuf = new BYTE [ImageWidth * ImageHeight * 4]
などとしているのだろうか。
>>653-656
void *pSrcBuf;
LONG Pitch;
pPxは、16bitの時がWORD*で32bitの時がDWORD*
という感じになってた。
初期化の部分がかなり複雑で結構辿って調べる必要があるんだよね…
でも思うのは初期化は、16bitと32bit大体同じで違うのはpPxの型くらいで
それで>>650の32bitのコードだと全然遅くならないから
>>651の16bitのコードの部分自体が何か変だったのかなと思ったんだけど
ここ自体は大丈夫なのかな? そもそも遅くなるって何分が何分になるん?
100分が103分ならそんなもんじゃね?
としか思えないし
>>658
それが30秒が2分とか3分とかになっちゃって。 >>660
いやそうじゃなくて、>>636のダミーコードを入れると
何故か速い速度になって、それを取り除くと遅くなってしまう感じ。
普通にコード書いてても関係ない部分を追加したりすると遅くなったり
速くなったりするからおかしいなと思ってて。 >>661
なるほど。では、
>初期化の部分がかなり複雑で結構辿って調べる必要があるんだよね…
であったとしても、原因を特定するには、少なくともまずそこを丹念に
調べる必要がある。 >>661
とりあえず遅いコードと速いコードを晒してよ
バッファーオーバーランで制御変数壊してるとかあるかも知れんし >>661
そういえば、速い時でも30秒もかかっていることはとても気になる。
>>650 のコードだとどれくらいの時間になるの?
経験と勘で言えば、そのような平易なコードで30秒も掛かって、
時と場合により3分もかかるという現象が起きる場合、キャッシュ
が乱れている可能性がある。
もしかして、どこかで極端にメモリーをランダムアクセスしてない?
巨大なメモリーの中を、極端に不連続な場所をあっちこっちアクセスすると
キャッシュが聞きにくくなって、急激に遅くなることがある。 >>662
確かにそこは念入りに調べる必要がありますね。
>>663
それが本当に>>636をまったく関係ない部分に入れるだけで
速くなったりしてて。普通にコード書いてまったく関係ないところ追加したりすると
速くなったり遅くなったりするんだよね。一旦速くなったら弄らない限り遅くなる事はなくて
逆に一旦遅くなったら弄らない限り速くなったりする事はない感じ。
>>664
読み込んでメモリ操作する部分自体はかなり多い数をやってるので
20〜30秒くらいかかる時もある感じ。
読み込みとメモリ操作の部分で細かくメモリ確保と解放をやってるので
それのせいもあるのかな? >>665
>読み込んでメモリ操作する部分自体はかなり多い数をやってるので
>20〜30秒くらいかかる時もある感じ。
話を総合すると、
>>650 のコードが、「20〜30秒くらいかかる」が、
>>651 のコードが、速い時には「30秒」
ということになるが、コードを見る限り、651のコードは650の
コードの10倍以上かかっても不思議ではないコードになっているので、
この速度差はむしろ、少な過ぎる。
むしろ、>>651のコードは「3分」かかっている方が、
長年の経験と勘では正常に思える。 読込とか細かいメモリー確保とかコードに無いこと言われてもエスパーじゃないのでどうしょうもないな
悪いけど情報出せないなら他でやってくれ
>>666
今チェックしたら650の方が少し速かったですw
650が12秒くらいで、651が22秒くらいでした
これが速い場合で、651が遅い場合は2分くらいでした。
650は遅くなることがないです。
>>667
ほんとうにそうですね。
とりあえず晒した所が大丈夫なら
他の部分は自分で調べてみようと思います。 >>668
>今チェックしたら650の方が少し速かったですw
>650が12秒くらいで、651が22秒くらいでした
>これが速い場合で、651が遅い場合は2分くらいでした。
>650は遅くなることがないです。
これだけでも重要なことが分かる。以後は、処理時間に関する(数学的な)定量的な話になる。
まず、650と651の速度差が1.8倍程度しかないことからすると、
pSrcBuf と pPx の読み書きに相当時間が掛かっていることを示唆している。
650と651のソースを比較した時、計算部分の処理がとても増加しているが、
読み書きはキャッシュまで考慮すると、650と651で差が出ない。
651では、pSrcBufからは何度も読み込まれているが、最初に一回読み込まれた後はキャッシュに乗っているため、
複数回読んだからといって時間増大の原因にはなりにくい。
651では割り算や掛け算の計算量が物凄く増えているのにそれが比率にして 0.8 にしかなっていない。
(割り算や掛け算は本質的に遅いことはこの議論に置いて重要である。)
大量の割り算、掛け算に掛かっている時間が 0.8しかないのに、高々1回ずつのメモリーへの読み書きが 1.0 の時間
かかっていることに着目すると、1ピクセルあたり、データバス-CPU間の転送の観点で言って、
pSrcBufからの「一回の」読み込みとpPxへの一回の書き込みに、かなり時間が掛かっていることを意味する。
データがキャッシュに乗っていれば、ここまでの時間が掛からないので、
長年の経験と勘によれば、このような事態が起きたとき、CPUの中のすべてのキャッシュを一掃してしまっていることが多い。
だから、例えば、バックグラウンドで他のアプリが動いていたりすると、キャッシュを
復活させるために物凄く時間が掛かることがある。
それで、他のアプリがメモリーを復活させようとしたかしていないかによって、
OS全体としての処理時間が如実に変わる現象が起きることがある。
これが、今回の奇妙な現象が起きている原因かも知れない。 >>669
細かい分析ありがとう。
だとしたら>>636のダミーを入れると速くなるのも
そのキャッシュの原因に何か関係してるのかな?
でも今まで>>665でも書いたように一旦遅くなったら
遅くなったままで、速くなったら速くなったままなんだよね… コード弄らない限り。
もしかすると何か条件が重なればコードを弄らなくても遅くなったり
速くなったりすることもあるのかもしれないけど。今のところは確認出来てない感じ。 >>670
それより、650のコードで12秒も掛かっていることにかなり違和感を覚える。
ImageWidth が、ImageHeight が 2000 位までなら、4*10^6 ピクセルくらいで、
32BIT RGBカラーだとしても16MB位。
いまのCPUだと、>>650のコードくらいで12秒も掛かるはずは無い。
大雑多な予測だと、3.0GHzのCPUで、10(ms)くらいまでのはず。
ImageWidth や ImageHeight の値はいくらくらいになってる? 650は最適化で X も x も同じ値で遷移していくし内側のループは
memcpy 相当のブロック転送におきかわりそうだけど
>>671
大きな画像(2048*2048)とかを結構読み込んでて。
読み込み処理自体は他の部分もあるのでそのくらいになってしまってる感じ。
>>672-673
一応は650にすれば何の異常もなくとても速く動作はするんだけど
出来れば原因が知りたいと思ってて。難しいならもうあきらめるけど。 >>674
ファイルから読み込んでるらしいけど、fseek をループの中で多数回使うと
使わない場合と比べて劇的に遅くなるけど、seek 系の関数は使ってない? ファイル読み込みの部分でHDDキャッシュがかかってるかどうかだったり
よくある話
色々と試行錯誤してたら
>>651のコードのこの部分を
for(int x = 0; x < ImageWidth; ++x){
このように書き換えたら普通に速くなったw
for(int x = 0; x < ImageWidth / 1.0f; ++x){
なんか最適化が効いたり効かなかったりみたいな差に感じてしまう。
そういう原因なのかな? >>674
2048 * 2048 ドットの画像だとベタデータにしたとき16MBになってしまうので、
それを沢山読み込むとメモリー不足になり仮想記憶が働いてしまっている可能性も
有るかも知れない。どれくらいの枚数読んでいるか知らないのでなんとも
言えないけど。 >>677
使ってるのはVisualStudioのようだけど、速度を測定する時には、ちゃんと
Release版にして最適化は有効にしてる?
DebugPrintを使っているなら最適化はOFFになってるのでは? >>678
でも>>677の修正で速度が劇的に変化するのはなんでなんだろう?
>>679
Releaseで調べてるよ。OutputDebugStringはReleaseモードでも使えるので。 >>677の修正をしたあと、>>636のダミーコードを
追加したらなんと今度は遅くなったwwなんでだ?w
>>636のダミーコードだけ追加したら速くなって
ダミーコードを削除すると遅くなる
その遅くなった状態で>>677の修正をすると速くなる
その速くなった状態で>>636のダミーコードを入れると
今度は遅くなるww 状況から察するに、おそらく君が見ている部分じゃない
どこかに根本的な問題がある、という気がする
なんとなくだけど、バッファオーバラン系のような気がする
>>682
どこかに問題がありそうですよね。
バッファオーバラン系は問題あっても動いてしまう事があるから怖いですね。
地道に調べて行くことにします。 それより、12秒間も大量のメモリーを使う状態でCPUがフルパワー状態になっている
とすれば、フル・キャッシュ汚染してる可能性がある。
フル・キャッシュ汚染すると、その後しばらくの間、キャッシュを取り戻すために
速度が不安定になるから、説明可能。
Meltdowm や Spector 対策のパッチの影響とか?
特定のパターンのメモリアクセスに対して例えばなんかのトラップが働いてキャッシュをクリアし、ダミーコード入れるとそのパターンが崩れてそういう処理が入らないとか。
>>684-685
みなさんありがとうございます。
色々な問題が考えられそうですね。参考になります。
もう少しコード弄りながら挙動を調べて行きたいと思います。 >>686
なお、y方向に関して、メモリーを上下逆さまに読んでいっているところがあるが、
本当はそういうのはDDR-Memoryやキャッシュと余り相性が良くない。
しょうがないけれども。
それでも、x方向には「順方向」に読んでいるからまだなんとかなっている。
完全にメモリーを逆方向に読んだりすると、低速化の原因になる。
この場合には難しいが、なるべくならメモリーは順方向にアクセスした方が
速くなる。DDR-MemoryはBurst転送が基本なので。
キャッシュに乗っていれば、逆方向でもなんとかなるが、キャッシュから
外れると、DDR-MemoryのBurst転送とは逆方向にアクセスするのは
速度低下の原因になる可能性が出てくる。絶対ではないが。 >>687
そういう問題もあるんですね。とても詳しくて勉強になります。
ありがとうございます! >>687
読み書き方向が逆になるなら、読む方を順方向にすると良さそうだと思うけどどう思う? >>689
実は昨日の夜から、俺もそう思ってた。
今は、
読む方が逆方向で、書く方が順方向になってしまっているが
読む方を順方向に、書く方を逆方向にした方が DDR-SDRAM や キャッシュの
仕組みから行って速くなる可能性が高い。 Windows の bitmap で ファイル中の配置や CreateDIBSection() で戻ってくるメモリの配置だな
デフォで bottom - up の方向 カメラのフレームとかは top - down な方向
ん?メモリ操作なコードだけど実はメモリマップドファイルだったりして
走査線と描画が重なったらチラツキが激しくなるから下から描いていくんだよ
for(int a=0; ...; ...){...} とかはループ内だけのスコープで int a が使えるのに
int a;
while(a){...}
とか
int a;
do{...}while(a);
とかは
while(int a=...){...} ←これだけはOK?
とか
do{...}while(int a=...);
とか
do{int a; ...}while(a);
みたいに書けないのはなぜ?
do{...}while(int a=...); 宣言より前に変数を使用する
do{int a; ...}while(a); スコープの外に変数を持ち出す
>>694
C/C++ の理屈では波括弧の部分は繰り返しの構文 (do や while) の一部ではない。
たとえば while の文法は
while ( expression ) statement
というように定義されていて、 statement ってのは要するに文をひとつ書けるってことね。
で、 statement として複文 (波括弧によって複数の文をひとつにまとめたブロック) もありうるってことになってる。
そんでもってブロックの先頭で宣言された変数のスコープに関するルールはブロックのほうに書かれていて、
繰り返しの構文のときだけ特別扱いということは出来んのだわ。
> while(int a=...){...} ←これだけはOK?
これは C++ では良いけど C では駄目 小さいスコープの中だけで使う自動変数だってんで
特に if や for 等なく いきなりカラス括弧開いて変数宣言することがままある
C++ってOSレイヤで差異が有るファイルシステムの事を考慮せずにプログラムを書ける済む仕組みって組み込まれてるの?
標準ライブラリに含まれるファイルシステムライブラリでできる範囲の操作なら差異は出にくいと思うけど
>>694,696
C++でもwhileの判定式中の宣言は毎回新しくなるんで、使いみち思いつかん。
while(int i=10) { i--; } は、無限ループになる。
できるとしたら、処理が終わったらすぐに始末したいobjに対して、
{ myclass obj(); while(obj) { obj.some_op(); } }
(obj は operator bool() とか実装してる前提)
が、
while(auto obj = myclass()) { obj.some_op(); }
こんな風にかけてちょっと{}がスッキリするくらい?(実際はobjが毎度構築される) >>700
まあ while(...){} は for(; ...;){} で書けるしメリットないかな
ただ
do{ int a = …; }while(a); の方は書けたら嬉しいな
使用頻度は低いけど do は do .. while(0) のパターンしか使わないな。
break用なら switch(0)default:{...} っしょ?
それdoよりどういうメリットある?
わざわざdefault:書かないとならないしインデント深くなりそうだし。
do{}while(0) は最後に ; 書く前提だし矛盾ないけど
switch(0)default:{...} は ; の扱いの困らない?
for (int i = 0; i < 1; i++)
{ } 内スコープからの脱出で break; 使いたいってのと
マクロで見た目関数向けな #define foo(arg) do { なんちゃらかんちゃら } while(0)
do { } while(0) は両立できるけど switch(0)default:{} で後者は怪しげ
if (<condition>) foo(arg); else <elsecase>; とかが
while(1){
...
break; // } の直前
}
で良いと思う
それどういう意図があんの?
処理は結局1回
スコープだけじゃダメなん?
>>710
お前が良いと思うなら使えばいいと思うが俺には無駄なbreakが必要なのはダサいと思うから do { ... } while(0); にするわ >>706
マクロはフォーマッタでの扱いが定まらんから制御構造では使いたくないのよな。
セミコロンで終端しておかないとインデントがおかしくなるとか、後続に開きブレースを置くと
やっぱりインデントが変になるとか。 #define breakblock switch(0)defalut:
でいいやん
できないとか怪しげとか意味不明
マクロ化する必然性がそもそもわかんないけど
そこまでして switch(0) 使う理由がよくわからん。
do while(0) と比べてどういうところが良いの?
マクロの例でもわかるように波括弧を単独で使える
変な処理が始まってんの一目瞭然
continueもgotoで(goto使わない別ルーチン探せよw
等
#define breakblock(a) uniqelonglongprefix##a:switch(0)default:
#define bbcontinue(a) goto uniqlonglongprefix##a
>マクロの例でもわかるように波括弧を単独で使える
ようは末尾に while(0); を書かなきゃならないのが嫌ってことかな。
わからんでもないが、自分はマクロや default: より気にならないからいいや。
#define foo(arg) switch(0)default:{ なんとかかんとか }
これはキモイ
でもその構文はdefineで置き換え前提で使ってるとしか思えない
goto書くと死んじゃう人は大変だなぁ
Dijkstraもそこまでは言ってないらしいぞ
ナンチャラカンチャラの人のdefine使用意図が無意味すぎてどうもc言語エアプなんじゃないかと疑う
switchのやつは最後にbreakかfall throughってコメント書いとかないと文句言うチェッカとかありそう
do {
int a;
:
} while(a);
↓
for(int a;;) {
:
if(!a) break;
}
でいいんじゃない?
別のところで質問したのですが、初心者歓迎スレのほうがいいと思いこちらで質問し直します。
Macのclang++でコンパイルしています。
cstdlibをインクルードしなくてもrand()が使えてしまうのですが、これはなぜでしょうか?
>>724
手元のM1のでやったら普通にエラーになるけど?
printf("%d",rand());
だけ書いたやつ。
clangでもデフォはエラーだったような。C言語の方はコンパイルオプションで通せる。暗黙の関数宣言。
すまん、役に立てなくて。 >>724
ヘッダファイルが他のヘッダファイルを内部で include している場合は有りうる。
たとえば iostream を include したら自動的に ios や istream なども include されることは保証された動作。
ただ、 cstdlib を (間接的に) include すると仕様で明言している標準ヘッダはないと思うので
rand がどこかで勝手に宣言されているのだとしたら処理系の固有の動作だと思う。
-M オプションで (間接的に include されているものも含めて) 依存関係があるヘッダファイルを
抽出できるからそれで確認できるよ。 >>725
ありがとうございます。M1のclangではエラーが返るのですか…。コンパイラのバージョンの問題ですかね?
>>726
ありがとうございます。-M試してみました。
インクルードはiostreamだけにしていたのですが、ぞろぞろヘッダーファイル出てきまして、その中にcstdlibもstdlib.hもありました。
iostreamのインクルードを外すと当たり前でしょうが、それらのヘッダーファイルは表示されなくなりました。
つまり、iostream以下のヘッダファイルの依存関係にcstdlibがいたということですよね?
これは処理系依存なのでしょうか? >>727
処理系依存だと思う。
iostream が暗黙に include すると仕様に明記しているのは
ios, streambuf, istream, ostream の 4 つ。
https://timsong-cpp.github.io/cppwp/n3337/iostream.objects.overview
あえていうなら cstdio の機能と結び付けるのが役割であるようにほのめかされている
ので普通の実装なら cstdio も include することになると考えてもいいと思うけど、
それ以上のことについてはっきりしたことは書かれてない。
rand が必要なら (たとえ実態として間接的に cstdlib が include されていても)
プログラマは明示的に cstdlib を include するほうがいい。
というか、そもそも論としてはいまどき rand を使うのは避けるほうが賢明な考えだと思うけどね。 >>728
なるほど、そもそも論まで含めてよくわかりました!
ありがとうございました! C言語にpthreadを使ってマルチスレッドにするときの初歩的な質問をしたいのですが、
大域変数を複数のスレッドが読み書きする部分はミューテックスでロックしないとマズい、という
説明はわかった気がします。
では読むだけの部分はどうでしょうか。単にスレッドが変数の値を読みに行った瞬間の値を
知りたいだけならば、別にロックはしなくても害はないような気もしますが.... プログラム内の
別の箇所で書き込む部分はロックして、おかしなことが起こらないようにするとして。
それとも読むだけの場合もロック(書き込む場合に使うじミューテックスでロック)は必要でしょうか。
>>730
スレッド実行中に書き換わる可能性があるなら必要。
変数を読むといってもCPUは一度内部のレジスタに読み込まないと処理できないので、
スレッド1でレジスタに読み込む→スレッド2で変数を書き換える→スレッド1に結果が反映されない
という事態が発生する可能性がある。 >>733
それ反映する必要ないだろ
単にスレッド1が先に読んだだけだし
それより読み書きがアトミックでないなら読み出し時にも排他しないと書き換え中の変な値を読んじゃうかと ええ場合もある
「単にスレッドが変数の値を読みに行った瞬間の値を知りたいだけ」はそれでええ場合のように聞こえるな
ええ場合も何も読んだ後で書き換えられたのをどうやって反映させるつもりなんだよ…
関連する操作すべてを優先順付きキュー経由にし
巻き戻し必要な操作にはジャーナル機能も入れ
やり直し再キューすんのよ
別スレッドからflgをいじって停止できるように
while (flg) {...}
と書いても、{...}の内部でflgをいじってないなら、
最適化で単なる無限ループに書き換えられて、flg変えても止まらない、
みたいな話なかったっけ。
>>739
それはまた違う話
volatile c言語 とかでぐぐれ スレッドAが 16bit長の整数を書き換える
スレッドBが 同じ16bit長の整数を読み込もうとしたとき
8bit長でしかアトミックな操作が保証されてないシステムだと
初期状態 0x0000 で スレッドA が 0xFFFF と書き換える
A書き込み 上位FF
(スイッチ)
B読み込み 上位FF
B読み込み 下位00
(スイッチ)
A書き込み 下位FF
こういうことが起き得るという話でいいんかな
>>734
いや、先に読んだだけっていっても、例えば
i f (v==1)
みたいな条件式を評価した段階では1だったけど、その先で急に2に変わった、とかだったらまずいだろw 質問者の文言が
>単にスレッドが変数の値を読みに行った瞬間の値を知りたいだけ
>読みに行った瞬間の値を知りたいだけ
なので必要なし
以上
>>744
ifの中ではもう一度vの値を読んだときには2になってたりするわけよ
vが1の前提で書いたコードの中に2を突っ込んだらまずいよ >もう一度vの値を読んだとき
まずいのはこっちであって>>742のifや>>733自体は問題ないんでは。 質問者が言ってないことに加えて勝手に仮定を追加してまずいとか言ってる>>745はもう黙ってほしい >>749
at least one of which is not atomic
の意味ぐらいは理解してからレスしなよ >>749
質問者は衝突しても問題ないケースで排他は必要かどうかを聞きたいんだろ 「衝突しても問題ない」&atomicも使わない=「データ競合となっても問題ない」=「動作が未定義でも問題ない」なら
確かにロックは不要だけど。
730です、どうもお騒がさせしております。
どうやら読み出しだけのときも基本的にはミューテックスを使うべきのようですね。
私の場合は域変数をカウンタとして使っていてその値をログ出力する、というような状況で、
なんとなくミューテックなしでもいいかと思ったのですが、ミューテックスを使わない場合は
気持ち悪い値がプリントされている感じですかね。
一般的な状況では、ミューテックスを使わなくても実害がないかを考えるよりはちゃんと
ミューテックスを使った方がよさそうですね...
「今値を書いてるから 書き終わるまで待て」と待たす相手は
次にそこへ書き込むヤツだけじゃなく
そこを読込もうとしたヤツも対象にしとけば ちゃんと書き終わった値が読込める
中途半端に書いてる最中であっても意図的に抜き出したいのなら 書き終わるまで待たずに読む
そしてみゅーてっくすの激しい握り合い
>>753
単純なカウンタみたいなアトミックに読み書きできるような変数なら排他は不要だよ >>756
>>749のリンク先読めばわかると思うけど競合が発生して結果が未定義になるのは
> at least one of which is not atomic
のケースね >>757
そこで言ってる "atomic" の意味は std::atomic<int> ならOKで int はダメという話なんだけど、
「単純なカウンタみたいなアトミックに読み書きできるような変数」って言い換えちゃったらどっちもOKに読めちゃうでしょ。 >>758
intがダメなのは>>741みたいなケースね
> 「単純なカウンタみたいなアトミックに読み書きできるような変数」
でだめだと言うなら実例教えて 単純なカウンタがアトミックに読み書きできるかは
基本型の宣言だけではわからんから
アトミック化の指示ができるならやっとけ ということでいいんでないの?
>>760
そのスタンスでいいと思うよ
俺はアトミックに読み書きできるケースなのに嘘とか言ってる>>756がなんか特殊なケースを知ってるのかな?って思ってるだけ 指示ができない場合にはアトミックに操作できる保証なんてないから
排他したほうがいいぜって立場
>>759
生の int に複数スレッドから排他なしでアクセスしてたらその時点で未定義動作=ダメなんだってば。
未定義動作となる場合に必ず期待に反するコードが生成されるわけでもないんで、実例を出せというのも意味が無い。
(実例が無いからといって「敢えて」未定義動作に誘導するというのは意味が無いどころか有害。)
・・・スレッドサニタイザで引っかかってウザい、とか言えば「実例」として納得してくれるの? 生のintへのアクセスがアトミックに行えるかって処理系が保証したりしないのけ
>>764
保証してる処理系なら std::atomic<int> でオーバーヘッドは生じない、つまり排他は要らんってことでしょ
>>756がなんか実例知ってるかと思ってたけど単なる規格厨だったなw >>766
オーバーヘッドが生じるかどうかで考えてるなら(それもおかしいんだけど)、こんな例を見れば考えを改めてくれたりするの?
https://godbolt.org/z/6oM5oevsY
#include <atomic>
int load(std::atomic<int> const& x) { return x; }
int load(int const& x) { return x; }
↓ARM64 gcc 11.1 -O2
load(std::atomic<int> const&):
ldar w0, [x0]
ret
load(int const&):
ldr w0, [x0]
ret >>767
それメモリーバリアの話で排他の話じゃないけど、何を言いたいの?w >>768
766 が「オーバーヘッドは生じない」ならば「排他は要らん」という論理らしいので
「オーバーヘッドは生じない」を否定すれば「排他は要らん」とかいう嘘を言わなくなってくれるかなと思って書いてみた。
オーバヘッドの発生と排他の要・不要とが 766 の頭の中でどう繋がってるのかは知らない。 >>769
まあメモリーバリアも一種のオーバーヘッドと言えなくもないがそういう話でないことぐらいはわかりそうなもんだけどねw
で、排他が必要な例は見つかったの? >>770
ごめんよ。元から意味が分からなかったところ「オーバーヘッド」の意味が何か文字通りの意味じゃなかった
みたいだし、もうどういう話なのかさっぱりだわ。
767 の「オーバーヘッド」が何を指すのか、それと排他の要・不要との繋がりがわかるようだったら解説よろしく。
「排他が必要な例」と言われても、こっちとしては複数スレッドで生の int を読み書きするなら
常に排他が必要という認識なんで文字通り「排他が必要な例」なら無数にあるんだよね。
そういうのを挙げても謎理論で「不要だろ」とか「コレジャナイ」って言うだけで話は進まなさそう。
ここまでの流れを読めば >>755 をうっかり信じちゃう人もいないだろうし、もう放置でいいかなという気になってる。 >>771
あえて指摘しなかったけどstd::atomicでは既定のメモリーオーダーがseq_cstであることを知らんのか?
自分で「あんたの言うオーバーヘッド」かかる書き方してオーバーヘッドかかるから排他ガーとか意味不明なんですけど?w
そもそもstd::atomicは必ず排他かかるわけでもないし人を嘘つき呼ばわりするならもう少し勉強した方が恥をかかなくて済むと思うよ >>772
ごめんそれは知ってるよ。でもそれを知ってる知識レベルの人が >755 のような主張をしてるとは思わなかったんだ。
あと繰り返しだけど「オーバーヘッドかかるから排他ガー」とか言ってるのは >766 だけね。意味不明なのには同意する。
「std::atomicは必ず排他かかるわけでもない」は正しいけど、それと >755 が嘘であることに関係は無い。 >>773
> ごめんそれは知ってるよ。
えっ?
知ってて>>767ってそれこそ意味不明なんですけどw
結局何を言いたかったの?
> あと繰り返しだけど「オーバーヘッドかかるから排他ガー」とか言ってるのは >766 だけね。
ああマジで日本語の理解力がないのね
(もちろん環境によるけど)std::atomic使っても生のintと同じようにアクセスできる = 排他なんてしてない
って話ね
念の為に言っておくけど>>764が言うようなハード上の排他制御は別の話ね
> 意味不明なのには同意する。
同意なんていらんから>>767を書いた意味を説明してよ
> 「std::atomicは必ず排他かかるわけでもない」は正しいけど、それと >755 が嘘であることに関係は無い。
嘘だと言うなら根拠を示したほうが良いと思うよ
まあ示せないからグダグダ言うとか関係の無いメモリーオーダーの話とかにそらそうとしてるんだろうけど… >>774
「767を書いた意味」なら>>769で説明した。
「環境によるけど)std::atomic使っても生のintと同じようにアクセスできる = 排他なんてしてない」これは正しい。
でもそれは生の int でデータ競合を避けられる理由にはならない。
>>755 が嘘だという根拠は >>749 に挙げられた規定による。その条件
"at least one of which is not atomic" について、生の int へのアクセスは
"not atomic" に該当するから排他なしのアクセスでは未定義動作となりダメだと言っている。
規格文面の "atomic" は、規格が規定する C++ 抽象機械上の概念という認識。
対して 755 は、規格文面の "atomic" は各処理系でのメモリアクセスが実際にアトミックかどうかに依ると考えてそう。
残念ながら規格の文面で明確にその解釈を否定できないんだけど (https://cplusplus.github.io/LWG/issue2506)
少なくとも現メモリモデル策定当時から Web 上に積み上げられている多くの記事(標準化委員会の↑含む)や
現行コンパイラ(最適化、スレッドサニタイザなど)での扱いと合致しない。 >>775
> 「767を書いた意味」なら>>769で説明した。
あああのメモリーバリアと排他の区別もついてないアホ丸出しの説明ねw
> 少なくとも現メモリモデル策定当時から Web 上に積み上げられている多くの記事(標準化委員会の↑含む)や
> 現行コンパイラ(最適化、スレッドサニタイザなど)での扱いと合致しない。
百歩譲ってstd::atomic使えと言うのはいいけど、排他は必須じゃないだろ charはatomicなの?規格にどれがatomicだってあるの?
どれがatomicかなんて、CPU毎に違って当然だと思ってたわ
>>776
うん。データ競合を回避するにあたって std::atomic を使えば排他は必須じゃなくなるよ。
ミューテックスを使うなどの排他(順序付け)でも回避できて、どっちかでもいいし両方でもいい。
>>755 が嘘だという点には異論なくなったみたいだね。よかったよかった。 >>775
排他は要らんケースがあると言うだけの話
ちなみに>>755では生intなんて一言も書いてないけどね
std::atomic<int>でも多くの環境では
> 単純なカウンタみたいなアトミックに読み書きできるような変数になるしな
まあ結局規格ガーって言うしかないレベルの低い規格厨が関係のないメモリーバリアーとか出してきて恥を晒しただけだったなw C++ のバイナリ互換性についてお聞きしたいのですが。C++ のライブラリの中に以下のようなものが
あったとします。
class A { char *p1; };
class B { /* 略 */ };
class C { A a; B b; };
で、class A に新たな要素を追加して
class A { char *p1; char *p2; };
としてからライブラリを再ビルドし、以前のアプリのバイナリと混在させると、class C 内で a のサイズ
が変わる結果 b へのオフセットが変わりクラッシュするようです。
そこでふと思ったのですが、class A に最初から
class A { char *p1; char *p2; char *p3; char *p4; };
等と最初からある程度要素を確保しておき、必要に応じ上の方から使っていく、みたいなやり方は
アリでしょうか? (b へアクセスするときのクラッシュを防げるでしょうか?)
>>782
素直にC.aやC.bをポインタにすりゃいいだけちゃう? >>782
クラス定義が変わったのにそれを使う一部のコードを再ビルドしないってこと?
> そこでふと思ったのですが
> (中略)
> アリでしょうか? (b へアクセスするときのクラッシュを防げるでしょうか?)
ありかも知れんが、なんでそんな前近代的なやり方しないといけないのかを考えたほうがいいと思う C++ポケットリファレンス読んだ方いらっしゃいますか?
独習C++ 詳説 C++ 第2版の次に読もうかと思ってるのですが
近年の現場と言うか、
大手の製品開発や比較的規模の大きい案件とかで使われてるC++のバージョンってどの辺ですか?
未だにC++03ってわけないですよね?
>>786
C++プログラミング言語自体の研究という訳ではないのなら、
入門書以降は何か作る系の書籍のほうが良いのではないでしょうか?
物理シミュレーションだったりゲームだったり
人工知能だったりOSだったり様々あると思うので、
興味のある分野を極めていくのが良いと思います。
作りたいものがあるが何から手を付けて良いか分からないのなら
設計理論系の書籍等も良いと思います。
OOPを極めたいという考えであるならデザインパターン等も良いと思います。 どの道、
class C { A* a; };
と、ポインターに変えても、
class A { char *p1; char *p2; };
と、新しいメンバーp2 には、C を再コンパイルしないとアクセスできない
class A;
class C { A* a; }; だけで完結してるなら まぁ問題をおこしにくそうではあるけど
そこまでして C に関わるコンパイルを止めたい理由がわからん
>>787
最低でも C++11
それでも古いと思う C++って競プロ以外に何に向いてるの?なんで競プロに使われるの?
>>792
実行速度が速いことが多いから速度が評価の一部である以上は有利になる。
(速ければ速いほど良いというわけではないが、上限が設定されているのが普通) std::map<std::pair<const char *, int> > hoge;
のように const char * を key とするとき
hoge.insert(std::make_pair("A", 41));
hoge.insert(std::make_pair("C", 43));
hoge.insert(std::make_pair("B", 42));
と追加すると
hoge["C"] で 43 が得られると期待できますが
このとき make_pair したときの "C" と hoge["C"] の "C" のポインタは値が違ってても
同一 key とみなされますか?(ポインタの値ではなく文字の中身の一致を見てくれますか?)
あるいは char * だとまた変わりますか?
ポインターは先頭アドレス
2つのオブジェクトの内容が同じでも、
別々のオブジェクトなら、ポインターも異なる
ポインターが同じとは、同一のオブジェクトを指している場合だけ
追伸
一つの fuga.cpp 内で
二か所以上で "C" が使用されていたとき
同じアドレスにしてくれる機能もあるみたいですが
fuga.cpp と hage.cpp みたいに別のソースで
それぞれ "C" を使ってたりすると
勝手に同じアドレスにしてくれたりはないみたいで
いろいろトラブルのもとになりそうです
(どっちみち変数になってると手も足も出ませんし)
key は std::string にしておくか
あるいは
std::hash<>
と
std::equal_to<>
を定義して自分で比較する方が安全な模様
>>796
「あるいは」以降ってunordered_mapの話じゃないかい
mapならstd::less<>を定義する……というかデフォルトのstd::less<>が使われないようにユーザ定義比較関数をコンストラクタで渡す
俺もこういう場合はキーにstd::string使うからいいけども 今回の問題は
>一つの fuga.cpp 内で二か所以上で "C" が使用されていたとき同じアドレスにしてくれる機能もあるみたいですが
>fuga.cpp と hage.cpp みたいに別のソースでそれぞれ "C" を使ってたりすると勝手に同じアドレスにしてくれたりはないみたいで
これでした
stringにしたら解決です
ほんとうにありがとうございました
>>798 別のソースでも同じアドレスにしてくれることあるよ。 >>ってどのように言えばいい?
だいなり、だいなり
???
>>801
トークンとしての名前は無いと思う。
演算子としての名前なら右シフト演算子とか、
iostream 的な用途の場合は抽出演算子とも言う。 insertion/extraction operatorっていうのか。
stream operatorだと思ってたわ
>>802-803
念のために仕様書を見直して見たら抽出子 (extractor) だったわ。 Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しでView types参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴
著者: アンドレアス・ルンプ
バージョン: 1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、Cのソースコードを吐き出せるのでC言語でリモートワークされ
ている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しのView typesで参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴
著者: アンドレアス・ルンプ
バージョン: 1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、高速なCのソースコードを吐き出せるのでC言語でリモートワーク
されている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しのView typesで参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴 バージョン1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
第二プログラミング言語として Rust はオススメしません Nim をやるのです
https://wolfbash.hateblo.jp/entry/2017/07/30/193412
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、高速なCのソースコードを吐き出せるのでC言語でリモートワーク
されている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます unordered_map で erase(key) を実行した場合
要素のデストラクタは呼ばれるのでしょうか?
必ず自分で呼ばないとだめ?
あるいは勝手に呼んでくれるオプションとかある?
つまり
unordered_map<hoge, fuga *>
みたいなときって
fuga *f があるとすると
delete f されるっていう認識で OK?
ポインタ型のデストラクタは基本的に何もしない。
デストラクタで破棄したいならunique_ptrなどスマポを使う。
813ハノン ◆QZaw55cn4c 2021/08/22(日) 15:55:44.42
814ハノン ◆QZaw55cn4c 2021/08/22(日) 16:00:15.54
815ハノン ◆QZaw55cn4c 2021/08/22(日) 18:24:32.36
>>815
文字列リテラルを char* にキャストするほうがだいぶん行儀が悪いと思うよ。 817ハノン ◆QZaw55cn4c 2021/08/22(日) 22:10:22.39
>>816
しかし、MyStr のコンストラクタの引数が std::string とか、もう何やっているのかわからなくなる‥‥ >>817
???
const char* で受ければいいだけでしょ?
なんでそこで std::string が出てくるの? 819ハノン ◆QZaw55cn4c 2021/08/22(日) 22:23:59.15
>>818
そういう意味でしたか、const に対する注意力がまだ足りないのは私の課題ですね linuxのg++8.3でstd::stringのメンバ関数の
insert(const_iterator, char)を使うとコンパイルが通らないのですが、バグでしょうか?
-std=gnu++1zつけてます。
>>820
具体的に問題を再現するコードとエラーメッセージを書いて。 >>821
こんな感じです。
g++のバージョンは8.3で-std=gnu++1z でコンパイルしています。
-- ソースファイル
#include <string>
int main(int argc, char** argv) {
std::string str="abcd";
std::string::const_iterator it = str.cend();
str.insert(it, 'a');
return 0;
}
-- エラーメッセージ
testinsert.cpp: In function ‘int main(int, char**)’:
testinsert.cpp:6:21: error: no matching function for call to ‘std::basic_string<char>::insert(std::basic_string<char>::const_iterator&, char)’
str.insert(it, 'a');
^
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/string:52,
from testinsert.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:4419:7: note: candidate: ‘void std::basic_string<_CharT, _Traits, _Alloc>::insert(std::basic_string<_CharT, _Traits, _Alloc>::iterator, std::basic_string<_CharT, _Traits, _Alloc>::size_type, _CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]’
insert(iterator __p, size_type __n, _CharT __c)
^~~~~~ >>823
コンパイルできないのはバグだが終端イテレータの扱いについては
変遷があって有効なイテレータと見做されない時期もあった。
最後に文字をくっつけるのであれば push_back か append を使ったほうが無難。 >>824
> 終端イテレータの扱いについては
> 変遷があって有効なイテレータと見做されない時期もあった。
要出典 >>824
アドバイスありがとうございます。
やっぱり規格的におかしいと思って調べてみたところコンパイラがc++11に対応していないだけでした。
ありがとうございました コンパイラはver.4.8で対応してるよ
gnu++1zてのがないんじゃないの?
C++を勉強しているんだけど難しすぎる。
目標は研究に使う数値計算ライブラリを作ることでそのために、
オブジェクト指向とテンプレートプログラミングとSTLを勉強しているんだけど量が多すぎて発狂しそう。
本当にC++を仕事で使っている人はこの量の仕様を覚えて使いこなしてるのか・・・
基本的に自分がよく使う範囲だけ覚えて
必要があればそれ以外の範囲を調べて使う
膨大なようで、所詮言語だから使ってれば覚える
生半可に上辺だけ触って判った気になって
コード描けますとかいうやつと仕事したくないわ
>>827
>>828
言葉足らずですみません。
CentOS7のdevtoolのg++はABI互換性の関係から古いlibstdc++としかリンクできないようにされていて
つまるところC++11の機能はほとんど使えなくなっている、ということでした。
本来ver8.3ならC++17にも対応しているはずなのにほとんど意味ないわけです…。
だったら-std=c++11とかつけたときに警告してくれとでも思わないわけもないですが。 >>829
もしEigenとかみたいなメタプログラミング使った数値計算ライブラリを考えてるならやめとけ
無駄に開発期間が数倍から10倍程度に膨れ上がるだけ
とりあえずテンプレートとか使わずに(あるいはメタじゃないレベルにおさえて)普通に書いたら? >>829
仕事をすると言っても、他の人がこさえたライブラリを使う場合はそこまでは求められんだろう。
反対に根っこ部分のライブラリとか、チーム内でのルールに関わると知識と経験がいるんじゃないかな?
よく理解できている方法でしっかり組み立てられるようになってから、徐々に細かい話に手を出したらいいと思う。
他の方法は解ってるし悪いわけでもないが、記述が気に入らないので延々とtemplate弄り倒す沼もあるから注意してね。 数値計算に使うのならまずはSTL抑えておくだけでいいんじゃね?
C++言語自体の習得より、GPGPU、分散処理、SIMD、メモリ管理とかのノウハウ習得にまずは時間を割り当てるほうがよいと思う
物理の計算とか、いろんな数学的な量が出てくるけど、そういうのの演算がすべて
プログラム上では同じ形で書ければかっこいいなあと思ったり。
例えば、(スカラー)積なら、オペランドが実数、虚数、ベクトル、行列、テンソル....等々どれでも
乗算オペレーターで扱えるとか。
「普通」の数値ライブラリだとオペランド毎に積を扱う関数がうんざりするほどあってそれを適切に
選ばないといけなかったりするので。
829です。
皆さんいろいろとアドバイスありがとうございます。
自分が作ろうと思っているのは、Eigenを用いた金融系の数値計算ライブラリなのですが、テンプレートを用いたらいろいろな型を代入できて便利かな〜くらいの感じで作ろうとしていました。
templateの使い方自体は少し勉強してみましたが、メタプログラミングの概念自体もよくわかっていないので、ひとまずtemplateは後回しにしようかと思います。
オブジェクト指向で書くかどうかは実際にコードを書いてみてから考えてみたいと思います。
Eigen利用するだけか
それならまぁ無駄に時間かかるということも無いと思う(変なとこに拘らなければ
>>836
コンピューターというか主要な高級プログラミング言語が出来て50年以上経つが
だれもそういうことをやってないのは何故だと思う? ちなみに SciPy とか SymPy は良く出来てる方
>>839
template使ったらもう型にとらわれなくていいんじゃね?はC++学習者の必ず通る道やからしゃーない で、結局なんでできないの?
C APIのほうが汎用性が高いから?
行列やテンソルは乗算方法が複数あるから?
結果の表現形式も有理数とか複数あるから?
結果をエレベーションする必要があるから?
>>843
Cで開発するときに、常にヘッダファイルに書いておく必要があるかどうかって話なら、将来c++から呼び出す可能性があるなら書いておけば?
最悪なくてもインクルードする側でどうにかなる >>843
32bitとはいえマイコンで-std=gnu++17とか指定するのは微妙な背徳感を感じてしまうチキンだが、
Cのライブラリも一緒に使うから、普通に使ってるな。基本ヘッダファイルでほとんど事足りるんだけど、
weak指定のCの割り込みハンドラとか再定義するときは混乱しないように明示的にextern "C"付けてる。 void *q = (void*)p;
void *r = reinterpert_cast<void *>(p);
void *s = static_cast<void *>(p);
どっちが良い?
>>838
Eigen の MatrixXtype と Matrix<type, Dynamic, Dynamic> が便利なのは判ったが
自分でそいつらを引数に持つテンプレート関数書こうとして
template <typename T, int R, int C>
void func(Matrix<T, R, C>&m){ ... }
で定義したら
a が Matrix3d a; とか RC 固定されてるときは func(a) で問題無いが
a が Matrix<type, Dynamic, Dynamic> a(3, 3); だと
実際に func(a) とかで呼ばれるときに
Matrix<type, -1, -1>
で呼ばれてて Row 数も Column 数も判らないので
結局呼ぶときに
func<type, 3, 3>(a)
みたいに確定して呼ぶことになるんだが
そういうもの? Eigen使ったことないけど、それ多分動的なサイズ指定だよね
コンパイル時にサイズ分かってない奴じゃね
fstream で open するオプションで
ios:in ios:out ios:binary とかと
ios_base:in ios_base:out ios_base:binary とかと
何が違うのでしょう?
一般的にプリプロセッサのビットシフトに制限てありますか?
#define HOGE (1<<27)
だとダメで
#define HOGE (0x8000000)
だとOKだとかありますかね?
>>857
プリプロセッサはその define値をその記述通りの文字列(というか文)としか見てなくて、単にその定義名の所へはめ込むだけじゃない?
あとは嵌め込まれた後の文脈でコンパイラが解釈するんじゃないかな。 >>858
そう言われてみればそうですよね
トンチンカンな質問失礼しました >>857
定義での制限はないが、マクロの制御定数式として表れる場合、
つまり
#if HOGE > 0
みたいな前処理指令があった場合に全ての符号付整数型が intmax_t 、
全ての符号無し整数型が uintmax_t と同じ表現を持つというルールがあるので
通常の式とは解釈が違う。
(大抵の場合に intmax_t は long long int と同じ大きさだと思う。)
つまり普通の式としてならオーバーフローする場合でもプリプロセッサではオーバーフローしないこともあるので、
制限としてはむしろ緩い。
https://wandbox.org/permlink/Ns4Qt2xG3wj1WVBH std::listのsortを使ってるのですが
同値だった場合の順序が維持されず困ってます。
何かよい手はないですか?
比較関数を渡してるのですがその中で何とかならないでしょうか?
>>861
言語仕様上は std::list::sort は安定ソートなので
そうなってないなら標準ライブラリの実装が間違っているか使い方が間違っている。 >>862
そうなんですね。ありがとうございます。
調べてみます。 純粋仮想関数の通知メソッドの中から他所のアドレスを知りたい時C++だとどう書くのが一般的ですか?
私の同僚のプログラマがC++で、あるソフトのプラグインをdll形式で作成しており
そのdllファイルは6割くらいの環境では問題なく動作しています。
しかし、ユーザーの環境次第で動かないことがあり
dllをインストールした状態でソフトウェアを起動しようとすると、ソフトウェア自体が起動しないというバグを抱えており
この問題の解決方法は数か月以上、見つかっていません。
そのdllはWindowsのみで動作するものであり、MacやLinuxには対応していません。
Windowsの何らかの設定に関係するバグなのでしょうか…?
バグの原因が一切分からず、彼の作業が進まないので私の作業も進まず、困っています。
私自身はC++でそのソフトのプラグインを作成したこともないですし、彼に何のアドバイスもできないので
このスレッドのお力をお借りしたいです。
dllを作成する際にユーザー環境でデバッグしてログを取得する方法など
何でも良いのでアドバイスがあったら教えてください。
エスパーを求めています。
64bitと32bitの違い・・・ではないか
それかintel/amdどちらかにしかない命令使ってるとか、何か依存する部分があるとか??
まずはエラーメッセージをだな
でもランタイムライブラリのオプションがMTじゃなくてMDになってると予想
>>866
例外で落ちたりもせず、ただ起動しないの?
起動しない環境の特徴も分からない?
なにかしらのセキュリティソフトが入ってるとか。 >>866
>6割くらいの環境では問題なく動作
落ちる環境のPCで開発させてみるといいんじゃね そのプラグイン dll が vcのランタイムを要求してて 実行環境にvcのランタイムが入っていない
プラグインdllの性質上 ソフトが自前で LoadLibary するが、そこで失敗する
この際何が主因なのかわからないまま
静的なリンクなら ○○が見つかりませんdialog がでてすぐわかる
プラグインdll を Dependency Walker なりで そのDLLが必要としてる DLL を確認してみたら?
>>872
ソフトの仕様や実装次第だけど、プラグイン読み込みに失敗して起動しないアプリもちょっと手抜き過ぎだよね >>873
わかったとしても、「モジュール <プラグイン>.dll が見つからない」 としか書きようがなくてややこしい
※ 本当に見当たらないのは <プラグイン>.dll がさらにロードしようとしてる MSVCR○○.dll とかだから プラグインのロード失敗で 即exit するのも不親切かもね
グローバル変数かstatic変数使ってないか?
昔他所のモジュールと変数の書き換え合戦が起きて正常に動作しない事があった
>>876
static なら他所と競合しないんじゃない?
あとグローバル変数が仮に extern だったとしても、意図的にエクスポートしてなければ他所の DLL と競合はしないような。 拡張子dllでも独自の実装してるホストプログラムあるからなぁ…
それこそホストの開発者に聞くしかない
自前でできることは
1) DllMain の DLL_PROCESS_ATTACH、 DLL_PROCESS_DETACH に
printf を仕込んで 最低限 load がなされてるかを確認
2) load されてるのなら
最初に呼ばれるであろうexportしてる関数にがんがん printf を仕込んで 何処で死んでるかを確認
規格厨ほど仕事ができなくね
どうでもいいようなことにこだわってないで
さっさと仕事終わらせろよ
またお前か
何年立ったらルール覚えられるんだよ
つかえねーな
メンバ関数へのポインタで質問なのですが
class MyClass {
public:
void (MyClass::*p)();
void func();
};
int main() {
MyClass obj;
このようなクラスがあったとして
main関数でobjのメンバの関数ポインタpへfuncのアドレスを入れる書き方と
pを使ってfuncを呼ぶ書き方を教えて下さい
>>882
obj.p = &MyClass::func;
(obj.*(obj.p))(); C++でオブジェクト指向を学びたいなと思ってるのですが、みなさんはどのように学びましたか?
既存のゲームの機能追加などをサークルでやっていて、C++自体には慣れてきて次のステップに進みたいと思いました.
ただただ自分でクラス設計考えて実際に書いて、さらにそれをあちこちで使ってみるだけ
実際に書く、利用する、をサボると机上の空論しか語れない頭でっかちになる
初心者です。
自作クラスをVector型に押し込めようとしたのですが、そこで発生したエラーの解決方法を2時間くらい調べたのですが分かりませんでした。
class myClass
{
myClass(int A){num = A;}
void show() {
cout << "" << "="<<num<<endl;}
~myClass(){}
int num;
};
int main() {
myClass a1(1), a2(2), a3(3), a4(4), a5(5);
vector<myClass> myClassList;
myClassList.push_back(a1);
//中略
//削除するオブジェのインデックス番号を記録
vector<int> delList;
for (int i = 0; i < myClassList.size(); ++i)
{
if (myClassList[i].num == 2 || myClassList[i].num == 4) {
cout << "i" << "=" << i << endl;
delList.push_back(i);
}
}
cout << "削除開始" << endl;
for (int i = 0; i < delList.size(); ++i)
{
std::erase(myClassList, delList[i]);//コイツでエラー
}
return 0;
}
二項演算子 '==': 'myClass' は、この演算子または定義済の演算子に適切な型への変換の定義を行いません。
>>887
myClass::operator==を定義してみ。 >>888
オペレータに何を定義すれば良いか分かりません >>889
eraseの仕様を見れば内部で要素を比較していることがわかる。
そこでmyClassとintの比較を定義する必要がある。
bool operator==(int n) const
{
return n == num;
} あるいは
friend bool operator==(const myClass& my, int n)
{
return my.num == n;
}
蟻人間さん、ご丁寧に教えてくださり、本当にありがとうございます。
無事問題が解決しました
msvcのコンパイルが遅いのとメモリ大量に使うのとで大変辛いのですが、コンパイルだけ別の端末で出来たりしませんか?
VARIANT型をログ出力したいときはどうしたらよいでしょうか?
>>896
std::variant (C++17 以降) のこと?
それとも COM で使う VARIANT のこと?
それとも特定の実装 (または規約) ではなく動的型一般のこと? 何がわからないの?
基本的な数値型や配列以外の場合にどう文字列化すればいいかわからないってこと?
VARIANT.ToString的なのないかな?的な
みんな自分で作ってるの?
>>900
VARIANT は基本的な型だけでなく COM のオブジェクト (を指すポインタ) を含むこともある。
COM におけるオブジェクトは「少なくとも IUnknown インターフェイスは実装されている」という保証 (規約) があるだけで、
それをどのように表示できるのかは汎用的には決めようがない。
基本的な型だけでも簡易的に文字列化するものがあるとちょっとしたデバッグ用途などでありがたいというのはわからんでもないけど。 >>901
オブジェクトはそのポインタ値を表示とかよくある ログ用途だとアドレスだけでは意味が薄そうに思うけど……
(実行のたびに値は変わるだろうし、検証に使えない。)
少なくとも整数などではないという区別が出来れば十分ということはあり得るかな。
タイプライブラリがちゃんと用意されているなら型名などが取得できる場合もあるので可能ならそういう情報も欲しいけど、
いずれにしても「文字列にする」という要求はユースケースが多用すぎて標準的な機能として決め打ちはしづらい。
>>903
Aのルーチンで使ってるオブジェクトとBのルーチンで使ってるオブジェクトが同じかどうかはわかる
それ以上のことを知りたいなら個別に表示ルーチンを組むしかない ガチガチの初心者です
#include<iostream>
double func(double x){
if (x>0) return x;
else return 0;
}
double dfunc(double x){
if (x>0) return 1;
else return 0;
}
int main(){
for (double x=-1.0; x<1; x+=0.1){
std::cout << std::scientific;
std::cout << x << ",";
std::cout << func(x) << ",";
std::cout << dfunc(x) << std::endl;
}
return 0;
}
を分割コンパイルするためにmain.cpp、func.cpp、func.fにソース分割したいのですがどのようにすればよいでしょうか
>>905 その3つファイル作って切り貼りして保存すればいいんじゃね。 >>906
すみません、書き方が悪かったです。分割の仕方?切り貼りして保存する3つのファイルの中身の書き方が知りたいです。 >>907
なぜ調べもしない?
「C言語 分割コンパイル」でググりゃあ出てくるっしょ >>907 自分でやった結果を見せてもらわないと何に困ってるのかわからない。 >>905
どんな入門書にも書いてあるようなことを質問するのは嫌がられる。
学ぶ気がなく代わりにやらせようとしているように見えるので。
そんで関連する事柄が多いので質問が具体的でないと単純に情報量的にとてもここには書けない。
細々としたところで引っかかるのは当然あることだしそういうのは喜んで回答するから
何がわからずに引っかかってるのかもうちょっと具体的にして欲しい。
わからないことをまとめられないなら
とりあえず自分なりにやってみたらどうなったのか見せれば、
何がわかってないかこっちで推測できる可能性がある。 if (fp = fopen("file.txt", "W+"))
って書くと↓が出るんだけど?
warning: suggest parentheses around assignment used as truth value
if文では、代入と比較の混乱が深刻で、警告を出さなければいけなかったと聞いてるが。
>>913
強めの警告オプションを付けてたら言語仕様上の問題がないものでも良くない作法に対しては警告が出ることはある。
a && b || c
とかいう式でも (人間が) 優先度を勘違いしやすいから括弧を付けることを勧められるし、
インデントの付け方がずれてる場合とかも警告は出る。
余計なお世話だと思うなら大抵はオプションで抑制できるよ。 括弧でくくっただけじゃ文句いわれたこともあるので二重否定しとく
if (!!(fp = fopen("file.txt", "W+")))
C++17 以降では if 文の括弧の中に初期化を書けるようになった。
初期化の内容と判断に使う式をセミコロンで区切って書ける。
if (fp = fopen("file.txt", "W+"); fp)
このとき変数の宣言を書いてもよく、
if (FILE* fp = fopen("file.txt", "W+"); fp)
というようにすると、この変数のスコープを if 文の内側だけに制限できるので便利。
便利だから C にも導入して欲しい。
if括弧中で初期化なんて前からやってたことだし
今じゃ代入も初期化になったのか
>>921
以前は「条件が宣言でもよい」だったところに
あらたに「初期化文と条件のふたつを書ける」「初期化文は式、もしくは単純宣言である」というルールが追加された形。 デストラクタだけ書いてあってムーブできないクラスをメンバ変数にすると色んな所でコンパイルエラーが出て困りました
値ではなくポインタで持つか、自分のクラスででムーブコンストラクタを書いたらとりあえずはエラーが出なくなったのですが、
こういうクラスは一体どう使われるのを想定して実装したんでしょうか?
基底クラスからたくさん派生クラスを作りました。
基底クラスの1つのvirtualメソッドを、各派生クラスでoverrideしました。
基底クラスを指す箱から、派生クラスのメソッドを呼ぶ方法を教えてください。
多少スタイルを変えても実現する方法があればお願いします。
ただし、場合分けやインデックスで対応するのは(派生クラスが増えたときに修正箇所が分散するので)厳しいです。
コンパイラは最近のvisual studioのC++を使っています。
struct Basic{
virtual void work(){cout<<"Basic";}
};
struct B1:public Basic{
void work()override{cout<<"B1";}
}b1;
struct B30:public Basic{
void work()override{cout<<"B30";}
}b30;
void main(){
Basic basic_array[9];
basic_array[0]=b30;
basic_array[0].work();//基底クラスのメソッドが呼ばれて Basic と表示されてしまう。
}
Basicの配列にはBasicのオブジェクトしか入らないから、b30もコピーしたときにBasicになってしまったからだよ
Basic*の配列にするかvector<uniq_ptr<Basic>>を使えば
>>925
ポリモーフィズム成功しました。基底クラスのポインタを使って解決しました。
また、基底クラスの変数にコピーすると派生クラス独自のメンバが全て無くなることが理解できました。
ありがとうございました。
void main(){
Basic*basic_array[9];
basic_array[0]=&b30;
basic_array[0]->work();//B30のメソッドが呼ばれた。
} >>925
> vector<uniq_ptr<Basic>>を使え
動的にインスタンスを作り始めた途端に、コンテナとスマートポインタが必要になりました。
見事すぎる回答に改めて感謝します。 例外で飛んじゃうと後始末ができなくてメモリリークしちゃうんだけど
クラスでラップしてデストラクタっていちいちやる感じ?
try~catchで囲えば処理できるけど
すべての例外が出る可能性のあるコード全部try~catchしちゃっていい?
>>928
「いちいちやる」っていうか、同種のリソースを扱うときはいつも必要になる対応だからデストラクタでいいんだよ。
大抵はunique_ptrとか標準にあるもので済むし。 >>928
いちいち個別対応したくないからクラス定義に押し込めるんだよ。 >>931
今回のとこちょっとなんだけどなぁ
例外発生するとこ全部でやらなあかんやんコレ
クソ杉ちゃう? えー、わからんのー?
つまり例外が発生しうるとこすべてで
尻切れトンボされる可能性があって
以前のようにmalloc-freeのコードが混じってるとそいつらは問答無用でメモリリークしちゃうって話よ
>>932
対処する必要があるところで catch して解放するだけだろう。
それがどうして出来ないんだ? まあ、それよ
そういう対応が必要になるって話よ
追加するやつ全部trycatchで包むか
mallocfreeをクラスで包むか
入れたのは20行程度なのにルーチンの流れまで変える必要があったりなかったりで(# ゚Д゚) イラッ!
>>934
malloc-freeしてる既存コードに例外発生する処理を混ぜるなんて特殊状況ならしょうがない。
面倒な状況なのはわかる。あきらめて心を殺してtry catchするか小さいRAII用クラスを作るか。
あるいはmalloc-freeしてるところも標準コンテナやunique_ptrに置き換えていけばすっきりするかもね。 >>932
クソすぎかもしれないが、それは必要だし普通だろ メモリ解放以外にデストラクタでやることはあるわけだしな
集約して定義しとけよという
LinuxでyyyyMMddhhmmss.fffを出力する
一番簡単な方法を教えて下さい
printf("yyyyMMddhhmmss.fff");
GNU/Linuxを仮定
system("date +%Y%m%d%H%M%S.%3N\");
日付のフォーマットなんて都度調べるもんな
覚えてる変なやつもいるんだろうね
>>945
これやったら秒とミリ秒を別で取得してるので
秒が59.999(ミリ秒はイメージ)のときに
ミリ秒は00.002ってなるときに前回の値が59.857ぐらいだったとすると
59.002ってなってしまうので逆転が起きたときは前回の値と比較して
逆転してたらミリ秒を強制的に999にするとかダサイことやってるんですけど
マジでこんな方法しかないでしょうか? >>946
そのダサいことをやってるのは何行目?
見つからないよ localtimeが時刻取得だと思ったんじゃろうね
>>947
timespecで取得できるのがミリ秒だけだと思ってました
自分のプログラムでtime_tで取得できる関数と複合してたのが原因でした あー、だめだ
localtime_rがないって言われる
localtime_sもないって言われる
しばらくクソ方法で保留で
ビルドの設定いじってもらって通りました
ありがとう御座いました
【質問】
switch constexpr って無いんですか?
【背景】
if constexpr(false){
}
if constexpr(false){
}
if constexpr(true){
}
if constexpr(false){
}
という記法に疲れました。
switch(定数) で実現可能ですが、コンパイラがwarningを出すので避けたいところです。
>>957
早速の回答ありがとうございます。
否定的な解決で残念ですが、前向きに生きていきます! クロスプラットフォーム対応のキーボードイベント入力・マウスイベント入力があるライブラリで、規模がそこまで大きくないものって何かありますか?
>>960
情報ありがとうございます
ncursesだとWindowsで動かしにくいみたいなんでフォークのpdcursesでやってみます >>908
ググって出てこないようなことをおまえら答えれるのか? 日本語で記述された問題や目的から有用なページを紹介するのはグーグル先生は苦手なんだよ。
核心的なキーワード抜きだと特に。
スマホが普及しきった2015年くらいからGoogle検索の難易度一気に上がったな
昔はガバガバキーワードでもGoogle先生が忖度してくれていた
広告出してくれるインチキ医療サイトや適当プログラミングスクール優遇しまーす!!
無能
初心者歓迎ということで、ちょっと聞いてみたいのですが、c++の世界ではboostというライブラリは有名なのでしょうか?
c++で勤怠管理できるwebシステムを作るんだといってコンストラクタがなんだかわからないまま
boostを読んでヘッダファイルをいくつか読んだあたりで英語読めなくて投げ出したことがあります。
>>969
有名だけど、使わんほうがいいよ
標準で十分だよ >>970
ありがとうございます!!
それに、あなた有識者の方ですね?
もしよければ少しだけ詳しく評判を教えていただければ幸いです。 >>969
かなり有名で活発。
最初から標準化委員会の人がかかわってるし、 Boost が出自の機能が標準入りしたこともある。
ただ、実験的な要素も多分にある。
急に仕様がかわることもある。
適切な場面では適切だし適切でない場面では適切でないというごく普通の話なんで、
評判がどうこうというより何をしたくて Boost に関心を持ってるのか説明したほうがいいよ。 >>972
ありがとうございます。
boostは今はそんなに興味は持っていないんですが、今ちょうどMIMEタイプらへんのところを読んでいて、
そういえばboostにMIMEタイプって書いてあったなぁ、boostって業界だとどんな感じなんだろ?という感じです。
何となくなのですが、仕様が良く変わるから使いにくいと言う感じなのかな?と理解しました。 >>974
更に詳しく有難うございます。確かに抜き出しちゃえば変わらないですもんね。
他でも応用できそう。 boost自体は使う必要はないけど、boostのドキュメントを読めないやつも不要だよな
ドキュメントもしっかりしてるから、使うだけなら簡単に使えるし
>>976
ありがとうございます。
boostくらい軽く読めないならエンジニアになるなと言うことですね。
初めて3か月くらいなもんでポートフォリオの一つもないですけれど、
本当に読んでおきますね。 これから年単位でトレーニングが続くのに初心者がいちいちポートフォリョーポートフォリョー言うのは大変めんどくせえ感
boost有用性は分かっていてもコンパイル時間やらなんやらで本チャンに適用しにくいんだよなぁ
boostなんてtemplateで悪ふざけしてるだけだから
普通のアプリには使えない
VC++である動画を再生するのにコーデックのDLLが必要なのですが
予めレジストリにDLL情報を登録して、実行ファイルと同じディレクトリにDLLを置けば動きます。
でも他の環境でレジストリに登録するのが大変なので(権限がらみで面倒)、登録なしでどうにか動かす事が出来ないでしょうか?
DLLを参照とかしても無理でしょうか?
レジストリで何を登録してるんだろう?
関数をexportするだけのsusieプラグイン
なんかはレジストリ登録不要で利用できるけど
COMだろ
仕様が公開されてればLoadLibrary()して使えるんじゃね?
DirectShowやMediaFoundationのcodecなら自分で呼ぶわけにもいかんだろうな
みなさんレスありがとう。
>>984
たぶんこれなんですよね… やっぱ無理ですかね。 今見たら、Video For Windowsの機能を利用してるみたいでした。
こんな古いのを使ってるから専用のコーデックを使わないといけないのか。
コーデックはH.264用のDLLみたいですね。どうにかならないかな。
HKEY_LOCAL_MACHINEにプログラムから簡単に登録出来ればいいんだけど。
なんか良い案はないでしょうか。
権限が必要ならプログラムのマニフェストで権限を要求。
自動化が必要なら、必要なコマンドラインを調べてバッチプログラム化する。
>>987
ありがとうございます。調べてやってみます。 一般的な動画再生ソフトでもコーデックをインストールしないと見れないのがあるが
一方、コーデック内臓もあるので技術的にはインストール不要だとおもうが
やり方はしらん、どっちも
とりあえずはマニフェストの設定変更で、起動した時に権限要求するようにしました。
調べて更に良い方法あればまた変更するつもりです。みなさんレスありがとうございました。
SIMDの勉強中で、下のようなことをしたいのですが、コンストラクタでエラーになります。
プリミティブ型をアライメント指定してnew,deleteするにはどうすればいいですか?
class MyClass {
public:
MyClass() : member(new (std::align_val_t{32}) int[1000]) {}
~MyClass() { delete[] member; }
int* member;
};
コンパイラの吐き出すエラーは見た?
std::align_val_t を使えるのは C++17以降みたいだけど
そこらへんは大丈夫?
(※ ideone は C++14までやよね?)
>>992
C++20です。
visual studio 2022でエラーC2956が出ます。
エラーのリンク先には構造体をnewしたい場合の対処法が書かれてます。
対処法:構造体の宣言時にalignas()でアライメント指定する。
プリミティブ型を宣言することができない(?)ので、この対処法では解決できませんでした。 lud20230204105353ca
このスレへの固定リンク: http://5chb.net/r/tech/1594615908/ヒント:5chスレのurlに
http://xxxx.5ch
b.net/xxxx のように
bを入れるだけでここでスレ保存、閲覧できます。
TOPへ TOPへ
全掲示板一覧 この掲示板へ 人気スレ |
Youtube 動画
>50
>100
>200
>300
>500
>1000枚
新着画像
↓「【初心者歓迎】C/C++室 Ver.106【環境依存OK】 ->画像>1枚 」を見た人も見ています:
・ふらっと C#,C♯,C#(初心者用) Part132
・【Hook】フックの技術【Windows】
・最高に頭悪そうな発言してください in ム板 (VI) 2
・C++相談室 part137
・Vue vs React vs Angular vs Svelte Part.9
・Python上げVBA下げしてる気持ち悪い奴ら
・Google Maps API 質問箱
・パソコンのファイル整理中わい「これ半年前に暇つぶしに書いたプログラムやん、見てみよ」ポチ
・Visual Studio 2022 Part2
・Eclipse統合M36【Java/C++/Ruby/Python/Scala】
・プログラミングのお題スレ Part10
・【マウスだけで】Scratch【プログラミング】その1
・C言語上級者スレ
・HacktoberFest 迷惑行為 プルリク スパムでTシャツ貰おう
・えぇ、ですからVB6の開発はやめろと言ったんです。
・Android Studio Part3
・人工知能ディープラーニング機械学習のための数学
・ブロックチェーンの応用とか言うけどさ
・C言語なら俺に聞け
・シェルスクリプトは歴史が長いローコードです?
・VBScriptについて必死に話し合うスレ
・ユニケージってGPUで並列処理できるんかあぁぁん?
・文字コード総合スレ Part11
・オブジェクト指向を教えてくれ!
・古代VBプログラマ質問スレ(Ver.6.0 まで) part65
・写真の保存形式の著作権なんかあったよね?
・Androidプログラミング質問スレ revision53
・令和元年 vs 令和1年
・プログラム言語は増えすぎた
・Rust part10
・a4です。P2P人工知能「T」開発(2)
・ノーコードについて語るスレ【bubble】
・JavaScript の質問用スレッド vol.125
・【肥大化】C++ を見捨てたヤシ 2人目【複雑化】
・【信者】C++の問題点【アンチ】
・オブジェクト指向ってクソじゃね?
・JS初心者の集まるスレ
・Rust part6
・.NET CORE No.2
・AIは自動化と組み合わせることで人間の仕事を奪う
・【ER図】なんでもリレーション貼るの害悪じゃないかな?
・オブジェクト指向を教えてくれ!★2
・ オブジェクト指向を今すぐやってください
・Excel VBA 質問スレ Part75
・最近の奴は0.001秒で何命令実行できるかも知らない
・Excel VBA 質問スレ Part77
・Excel VBA 質問スレ Part51
・Pythonのお勉強 Part55
・【入門】Common Lisp その11【質問よろず】
・応用情報って取る価値ある?
・Win32API質問箱 Build23
・php使ってる奴はアホ、これからはRuby on Rails!
・go言語、python言語自信ニキ来てくれ
・アセンブラ 13
・Tizenアプリ作成
・【Enterprise】Java EEスレ part1【開発】
・結局Python上達するには何をすればよき?
・Ruby で GUI するスレ
・開発工数を大幅削減できた言語は存在しない
・Borlandにはやられた...
・どのレベルならプログラミング出来ると言っていい?
・新言語を開発したい
・【bzr】Bazaarでバージョン管理 Rev 4
・Microsoft SkyDrive API
・Amebaブログみたいなブログサイトが作りたい
12:26:17 up 8 days, 22:50, 0 users, load average: 7.03, 8.33, 8.80
in 0.050407886505127 sec
@0.050407886505127@0b7 on 122102
|