0からの、超初心者C++相談室

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2018/11/12(月) 14:55:13.35ID:Tf74ZWQr
何にも知らない0からの出発、超初心者のためのC++相談室
61デフォルトの名無しさん
垢版 |
2019/09/23(月) 11:55:25.99ID:3qdqqJ07
codecvtですね判ります
2019/09/23(月) 12:36:29.52ID:9Vk3Qf6P
>>60
正確には、トートロジー というより、循環論法に近い。
2019/09/23(月) 13:25:24.38ID:IaDL9t/N
>>60
たとえば cppreference のどの記事のことを言ってるんですか?
1つか2つでもいいんで、具体例がほしいです。
2019/09/23(月) 14:28:50.02ID:9Vk3Qf6P
>>63
もしかしたら >>60 の説明は「ずれて」いたかもしれないけど、例えば、言語仕様の
サンプルコードに高頻度に vector が出てくるので、それ自体がどうやって実装されているかを
調べることも重要になってくる。すると、initailizer-list なるものが重要であることがわかり、
vector の実装でそれがどう関係しているかも知りたくなる。それを知る前にまずは、vector template
の細かい仕様を調べたくなり、以下を見るとする:
https://en.cppreference.com/w/cpp/container/vector

↑は冒頭部分からしてこうなってる:
template<
 class T,
 class Allocator = std::allocator<T>
> class vector;
(1)
namespace pmr {
 template <class T>
 using vector = std::vector<T, std::pmr::polymorphic_allocator<T>>;
}
(2) (since C++17)
1) std::vector is a sequence container that encapsulates dynamic size arrays.
2) std::pmr::vector is an alias template that uses a polymorphic allocator

これは、初心者には難しすぎるし、実装を調べたいような上級者には情報が不足しており、
「帯に短し襷に長し」状態である(ちゃんとした説明になっていないのだ)。
上の部分を見た場合、最初に、allocator とはなんなのか、ということが疑問になる。
そして、allocator を調べなくてはならなくなる・・・・。

まず、vector とは何なのかが大まかに知りたかった人にすら、これでは難しい。
例えば、Ruby なら、[a,b,c] は、リストといって、集合です、と説明して
わずかなサンプルでもその全体像が分かった気がしてくる。
それとは全然違うことになってしまっている。
2019/09/23(月) 14:39:03.51ID:9Vk3Qf6P
>>64
誤:initailizer-list
正:initializer-list

vector の仕様を調べようとすると、(1),(2)の2つの定義が出ており、(2)では
なぜか、namespace pmr が出てきて、さらに、using vector = ・・・、で
vector という名前が alias で定義されているらしい。基礎の基礎を知りたくて
vectorを調べたのに、namespace と using alias が出てくる。そして、pmr
という namespace がいったい何なのかということを知る必要が出てくる。

まず説明に言葉が足りてない気がする。英語は曖昧さを含み易い言語らしく、
英語に強い人に聞いても「文脈でどっちとも取れるので正確な意味は分からない」
と言われる。日本語に比して言葉の意味が薄くて、サンプルコードが重要となる。
IntelのCPU命令のマニュアルだと、擬似コードで説明されている事があり、
その場合にはほぼ正確に言っていることが分かるが。cppreferenceはそれもない。
ほぼ、サンプルコードだけが頼りになっているが、そのサンプルも分かりにくい。
サンプルに対する英語の説明が少なすぎるから。
2019/09/23(月) 15:02:06.71ID:9Vk3Qf6P
>>64
時々、「コードこそがドキュメント」などという人がいて、それに従って
cppreferenceが書かれてしまっている可能性がある。しかし、vectorの
「仕様」とは、vectorが如何に実装されているかではなく、如何に使うか
の説明から入るべきなのに、>>64は、実装をモロに見せてしまってるから
難しくなっている。(1)のtemplate文だけでは、templateの仕様がまだ理解できてない
段階では、vectorの仕様を知ることが出来ないことになる。そう書くよりも、
いきなり、

std::vector<int> v = {7, 5, 16, 8};  // (100)

で、4つの整数型の要素を持つ配列を確保します。
メモリ上で要素は、隣り合わせに並びます。
配列の長さは動的に変更することが出来ます。

と書いたほうが良いし、完全な referece を書きたい場合でも、>>64 の(1)のように
書くべきではなくて、例えば、(100)を一般化して

[vector 型オブジェクトの作成方法]
std::vector<int> オブジェクト名 = 初期化子;  // (101)
 初期化子 := {初期値リスト}

などと書かないいけない。

>>64 の (1)は、vector自体の「実装方法」を書いているだけで
vectorの「仕様書」にはなっていない。
67デフォルトの名無しさん
垢版 |
2019/09/23(月) 15:16:09.23ID:3qdqqJ07
なるほど
それならトートロジーとか循環論法と言うよりも
もっと適切な言葉があるはず
2019/09/23(月) 15:21:18.30ID:9Vk3Qf6P
>>66
集合や、データベース系のソフトウェアでは、言葉は忘れたが、
初期化、追加、削除、参照、検索、個数の取得
などが良く使われる(ほぼ必須の)基本機能だとされるから、

[vector 型オブジェクトの作成方法]
std::vector<要素の型> オブジェクト名 = 初期化子;  // (200)
std::vector<要素の型> オブジェクト名 初期化子;  // (201)
 初期化子 := {初期値リスト}

[vector 型オブジェクトへの末尾への要素の追加]
オブジェクト名.push_back(要素);         // (210) 要素をコピーして追加したい場合
オブジェクト名.push_back(std::move(要素));   // (211) 要素を移動して追加したい場合

[vector 型オブジェクトの idx 番目の要素の参照]
オブジェクト名[idx]    // (220) : idx は先頭が 0 から始まる。
・・・

などと書いていけばよい(自分は細かい仕様が分かってないのでこれ以上詳しくは
書けないが、reference manual を書く人なら書けるはず)。
初心者が期待する reference manual とは上記のようなもので、
>> 64 のようなものではない。何度も言うが、>>64
実装と仕様が混合されてしまったもので、どっちつかずの状態になっている。
69デフォルトの名無しさん
垢版 |
2019/09/23(月) 15:26:14.73ID:3qdqqJ07
ソースから自動生成してるなら仕方ない面もある
70デフォルトの名無しさん
垢版 |
2019/09/23(月) 23:08:32.79ID:MNSCG3IB
実装で仕様が隠蔽されている
2019/09/23(月) 23:52:06.90ID:U2/CMzYE
大きい・小さいとか、言葉は、about で抽象的だから、
こんな厳密な事を決めるのには、向いていない

図解・サンプルの方が、圧倒的に理解しやすい。
だから、下の3冊などは、神の書と呼ばれる

サンプルを示すことで、OK/NG というのがハッキリわかるから!

C++11/14 コア言語、江添 亮、2015
組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド、MISRA‐C研究会、2006
Linux プログラミング・インタフェース、Michael Kerrisk、2012

理解できないような事を書いている、香具師が悪い。
そういうのを追っかけても、時間の無駄

プログラミング・フレームワーク・構造がわかるためには、Ruby でもやった方が余程よい。
C/C++ などポインタのある言語は、プログラミングを学ぶのに適していないし、
バグで時間を浪費するから、結局学べないw
2019/09/30(月) 10:42:32.26ID:6yDcPDBq
なるほどね
初心者にとっては
一度に多くのことを覚えないといけないのは負担が多い
生配列を使うのは良くないから最初からvectorを教えるのは
有る意味正しいけど
理解するには難易度が上がってしまっている

オブジェクト指向プログラミングでも同じ様な感じで
例の
動物クラスから継承して犬猫クラスを作ってワンニャン
とかの説明とかが良く有るけど
機能の説明としてはそれでいいんだけど
実際にそういう風には作らない(別にそういう風にやりたきゃやってもいいけど)
実際上は別な構造として作ったりするんだけど
その別なやり方をどうするのか?という説明が殆ど無いので
オブジェクト指向は糞
みたいな話になってくる
唯一の例題として有るのが
デザインパターン
だと自分は思っているが
あれを意味が無い
とか言っている人が結構居て
そのせいで軽視されているのが残念というか問題だと思ってる
初心者が手がかりにするのは難しい面も有るけど他に良さそうな例題が余り無い

適切な教科書を作る
というのは結構高度で大変で
作れる人が少ない
その割には作った人には余り金にならなかったりして
作ってくれる人が余り居ない印象
73デフォルトの名無しさん
垢版 |
2019/09/30(月) 12:08:38.76ID:vkIGDak2
gcc も g++ も VC も肥大化し過ぎた
digital mars c とか Borland C 5.5 かそれよりもっと前
tiny c compiler でもいい
初心者用にはもっとシンプルな C で充分
2019/10/06(日) 17:06:30.65ID:42LxT2AQ
quick c
2020/03/26(木) 16:08:19.66ID:71CdUQnj
>まず説明に言葉が足りてない気がする。英語は曖昧さを含み易い言語らしく、

英語は抽象意味言語だから指している範囲がザックリしてて
短い文章とかだと何を言っているのか解らない
その分覚えておかないといけない分量が少なくて良い
英語から日本語に自動翻訳を掛けても上手く翻訳されていない時はその文章が何の分野で有るか解らないから間違っている様に見えると感じる

日本語は一つの意味を指している事が多いけど覚えておかないといけない分量が多いから大変だけど
その分広い範囲の意味を指していないのでちゃんと使うと意味が一点を指して誤解し難い

けどプログラムを書く時は
javaだととりあえず.を書いておけば良いから迷わないけど
c++だと.だったり->だったり::だったりするから迷う事がある
そんなに致命的な問題では無いけど
76デフォルトの名無しさん
垢版 |
2020/03/27(金) 14:39:56.26ID:9RtDMjhb
::あんまり使わないな
2020/05/06(水) 18:31:54.91ID:K0jT0mUL
入門ロベールC++の188ページに

const char* MONTH_NAME[]={"睦月,"如月,"弥生"......  
というのがあるのですが、なぜchar*型の前にconstをつけると文字列リテラルをたくさん代入出来るのでしょうか?
const定数を外すと同じことが出来ないのがよく分からないです。ポインタが理解できてないのでしょうか。
2020/05/06(水) 18:38:37.65ID:wd9+jhuU
それの場合MONTH_NAMEの型は
「書き換えられないchar」「へのポインタ」「の配列」
であることがわかれば後はわかるっしょ
2020/05/06(水) 18:46:19.97ID:K0jT0mUL
>>78
すいません、分からないです・・・
何が分かってないからこうなってるのか。も分かってないからまた読み直して同じページに戻っても理解できないです・・
2020/05/06(水) 19:06:59.66ID:8YawtAIF
>>77
文字列リテラルの指す文字列は書きかえてはいけない。
char* の指す先の文字列は書きかえできる。
const char* の指す先の文字列は書きかえできない。
2020/05/06(水) 19:07:03.19ID:K0jT0mUL
何故文字配列なのに文字列を沢山入れられるのか…
2020/05/06(水) 19:09:49.04ID:8YawtAIF
>>77
あーわかった。あんたがエラーメッセージを読んで理解しようとしないから分からないんだよ。
2020/05/06(水) 20:16:45.31ID:K0jT0mUL
分かりません。
ポインタを直接文字列の値で初期化してるのもよくわからないです。
2020/05/06(水) 20:38:11.69ID:5oVnKxXT
char *s = "abc"; がダメな理由と
int a[] = { 1, 2, 3 }; がOKな理由を考えろ
2020/05/06(水) 20:47:05.11ID:Fjn1hDTG
const char* MONTH_NAME[]=

型 変数名[]

各要素の型は、const char*
[ ] は配列

最近、ロベールは本屋で売ってない
2020/05/06(水) 20:51:54.79ID:Fjn1hDTG
Ruby なら、変数名はラベルだから、変数に再代入できるけど

a = "a"
a = "abc"
2020/05/06(水) 20:53:56.70ID:K0jT0mUL
>>84
char* sはchar型の変数の参照が入ってないから駄目なのでは?
下はただの配列変数だからできてるのでは?
2020/05/06(水) 21:05:23.65ID:K0jT0mUL
>>85
const char*という新しい型があるのですか?
constとは定数を宣言するだけのものじゃないのでしょうか
2020/05/06(水) 21:49:00.63ID:K0jT0mUL
char* str[]={"aaa","bbb","ccc"}はできないのに
const char* str[]={"aaa","bbb","ccc"}はエラーにならないのも意味わからないです
const chr*のエンティティ云々も意味不明なのですがロベール188pまでにその説明は載ってるのでしょうか
2020/05/06(水) 21:54:43.49ID:5oVnKxXT
じゃあ const char *s = "abc"; がわからないのか
これはどこかにある "abc" という配列へのポインタでsを初期化しなさいっていう意味で、
char *s = "abc"; がダメなのは "abc" が変更不可だから

あとは const char *s = "abc"; と const char *MONTH_NAME[] = { "睦月", ... }; の関係が int i = 0; と int a[] = { 0, ... }; の関係と同じであることを考えればわかるはず
2020/05/06(水) 22:11:15.73ID:8YawtAIF
>>89
「できない」理由はエラーメッセージに書いてあるだろ。読めよ。
2020/05/06(水) 22:58:31.48ID:K0jT0mUL
>>90
文字列って定数なんですか?
何となく分かってきた気がします!細かく教えていただきありがとうございます
93デフォルトの名無しさん
垢版 |
2020/05/07(木) 12:23:12.56ID:iKRewGMt
>>77
const 付けたくないなら
char MONTH_NAME[][5]={"睦月,"如月,"弥生"......
94デフォルトの名無しさん
垢版 |
2020/05/07(木) 17:22:45.52ID:8jv+kISL
char r[] = "hoge";
char *s = "hoge";
const char *t = "hoge";
char *MONTH_NAME_A[]={"睦月","如月","弥生"};
char MONTH_NAME_B[][7]={"睦月","如月","弥生"};
どれもエラーも警告も出んかった
2020/05/07(木) 18:27:09.29ID:wkYaXeHy
char *t = "hoge";
これがエラーにならないのは言語上の欠陥
2020/05/08(金) 06:37:37.35ID:Br/73fC2
ロベールさんで紹介してる環境に限定されると語れる立場じゃないんだが…。

>>93
漢字1文字を2byteと仮定するのは危険じゃないかしら。
このごろUTF-8でベタに文字列書くことが多いんでちょい気になる。
と言ってu8プレフィックス付けるほどお行儀良くもない中途半端な人。

>>94
char *s = "hoge"; で警告出ないとは
ストラウストラップ先生がガッカリしそうなコンパイラね。
2020/05/08(金) 09:24:37.89ID:0HhOrENw
>>95
C++11 以降の言語仕様では許していない。
それより前の仕様では許していたという歴史的経緯があるので
(エラーではなく) 警告にとどめている処理系がまあまあ有るという事情。
2020/05/08(金) 09:31:38.60ID:oIDbptWL
C++
https://ideone.com/lWQYBs
C++14
https://ideone.com/2CLzMB

どっちもスルーされる
2020/05/08(金) 21:53:35.81ID:+i26a8kQ
ロベールの入門書に /*構造体変数student*/
int length = sizeof stundent /sizeof *student
というのがあるのですが何故これで配列の要素数が出るのでしょうか?
sizeof student / sizeof student[0]だと配列の要素数が出る理屈は何となく分かるのですが
配列とポインタは別のものですよね?
100デフォルトの名無しさん
垢版 |
2020/05/08(金) 22:21:29.33ID:/+tKw0XQ
student[0] と *student は同じ
2020/05/08(金) 23:07:29.79ID:+i26a8kQ
何で同じなのでしょうか?これで動くからこういうもの。という理解で大丈夫なんでしょうか
102デフォルトの名無しさん
垢版 |
2020/05/08(金) 23:48:12.63ID:xx+9oYGy
MSの陰謀。
2020/05/09(土) 06:15:34.68ID:LKKpAq9a
とりあえず stundent は誤りで正しくは student だとして

多くの場合、配列名は「配列の先頭要素を指すポインタ」と解釈される、から。
つまり配列studentについて student == &student[0] が成り立つ。
*演算子を作用させて *student == *&student[0] == student[0]
よって sizeof *student == sizeof student[0]

ここで注意すべき点は「配列名がsizeof演算子のオペランドになった場合は
配列の先頭要素を指すポインタとは解釈されない」ってこと。
sizeof 配列名 == 配列全体が占有するメモリ容量


なぜそうなっているか、という理由は「そう決めると便利だから」かな。
Cの頃からそういう感じでプログラム書いてたから、という歴史的経緯もある。

>>102 初心者をからかっちゃアカンよ。信じちゃうかも知れん。
104デフォルトの名無しさん
垢版 |
2020/05/09(土) 09:28:26.57ID:3rxWY8lS
コロチャンもゲイツの陰謀とか言ってる人が居てわろす
温暖化も陰謀ω
2020/05/09(土) 10:52:17.88ID:MmeKQuXy
>>99
「暗黙の型変換」によって配列がポインタに型変換されるルールがある。
スムーズにポインタとして使えてしまうから混同してわけわからんようになる初心者が多いんだけど、
あくまでも別物であるという理解が出来ているなら入門者としてはかなり優秀だと思う。

ほとんどの場合に配列はポインタに暗黙に型変換されるんだけど、
例外としては
 @ sizeof を適用するとき
 A 単項の & を適用するとき
 B 参照で受け取るとき
があって、これらの状況では型変換されずに解釈される。

----

余談だけど暗黙の型変換とは別に仮引数の調整というのもあって、
関数の仮引数として配列を書いた場合も配列はポインタに調整される。
たとえば
void foo(int a[10]) {}
という定義を書いたら
void foo(int* a) {}
と全く同じように解釈される。
2020/05/11(月) 03:00:46.06ID:II69MMpE
すいませんロベール持ってる人にお聞きしたいのですが
305ページの
for (int i = 0, size = a.Size(); i < size; ++i) という文があるのですが
このsizeというローカル変数は何処に定義されてるんでしょうか?
2020/05/11(月) 05:46:42.66ID:k4wInV7m
>>106
“ロベール本”を持ってないので答えられない立場かも知れんけど…。
この size は「ここ」で定義されているんだと思うよ。

for の初期化式 int i = 0, size = a.Size(); で、
「int の i」と「int の size」という2つの変数を定義している。
2020/05/11(月) 07:45:03.87ID:II69MMpE
>>107
forの中で2つ宣言できるんですね!そんな事も知りませんでした。
ありがとうございます。
109デフォルトの名無しさん
垢版 |
2020/05/11(月) 09:53:48.32ID:MhpqGE2N
型が違うときは?
for (long i = 0, int size = a.Size(); i < size; ++i)
2020/05/11(月) 19:53:43.37ID:8B6Lebzi
C++17なら
for (auto [i, size] = tuple(0L, a.Size()); i < size; ++i)
2020/05/21(木) 23:33:00.50ID:fIo5j0A9
class DataStore {
public:
DataStore(int v) : mValue(v) {}
bool operator==(const DataStore& rhs) const;

private:
int mValue;
};

bool DataStore::operator==(const DataStore& rhs) const
{
return mValue == rhs.mValue;
}

int main()
{
DataStore ds1(10), ds2(10);
if (ds1 == ds2) {}
}

というのがあるんですがoperatorに記述されてる仮引数はどっから実引数をコピーしてるのですか?
後演算子のオーバーロードに関して分かりやすく解説してるとこあれば教えていただけると嬉しいです
2020/05/21(木) 23:57:47.49ID:ut4Weg2U
operatorも、ただの関数
if (ds1.operator==(ds2)) {}
2020/05/22(金) 00:55:03.99ID:H9gcgSgg
const DataStore& rhsの実引数はds1ってことですか?
2020/05/22(金) 06:44:02.17ID:8neFOyTD
この流れだと、仮パラメータ rhs にバインドされる実引数は ds2 でしょ。

クラスのメンバ関数として宣言された2項演算子の operator OP(rhs) は、
lhs OP rhs と書くと lhs.operator OP(rhs) が呼び出される。
…と書いても分かりにくいね。


具体的には ds1 == ds2 と ds1.operator==(ds2) が同じ意味、
ってのが >>112 の人の言ってること。
2020/05/22(金) 09:23:45.22ID:JweU/zGV
余談だけど左右の引数が const な比較演算子は非メンバ関数として実装した方が好ましい場合が多い。
(標準ライブラリでもだいたいそうなってる。)
2020/05/22(金) 12:29:55.77ID:6NFPH2hn
constかどうかで決めるのはアホ
2020/05/30(土) 06:36:15.09ID:1Zwy+dfa
なぜ文字から'0'を引くと数字を数値に変換できるのですか? char c='8' int a=c-'0'
理屈がよくわからないです。
よろしくお願いします
118デフォルトの名無しさん
垢版 |
2020/05/30(土) 07:25:50.69ID:/FCD7s4m
順番に並んでいるから。
2020/05/30(土) 07:33:59.81ID:1Zwy+dfa
文字コードが順番に並んでるのは分かったのですが
なぜ'0'引くとキャストせずにint型の変数に代入できるようになるかが分かりません
よろしくお願いします
2020/05/30(土) 07:57:34.41ID:/LdiluDZ
'0'を引かなくてもキャストせずにint型の変数に代入できるよ
c/c++では文字は整数型に文字コードを入れて扱うんだよ
2020/05/30(土) 08:07:04.11ID:1Zwy+dfa
苦しんで覚えるC言語という本の255ページに
”数字を使うときには引き算で本来の数値を知ることも出来ます。
数字に持っ文字の番号が割り当てられており例えば'0'は48番に割り当てられてます。
数字から'0'の番号を引き算すれば数値に変換され計算に使用できます。”
とあるんですが
”数字から'0'の番号を引き算すれば数値に変換され計算に使用できま”というのが意味わからないです
2020/05/30(土) 08:27:53.58ID:CZP1xQZw
文字が元々数値(文字コード)であることが理解できてないのでは
ASCIIコード表でググってみれ
2020/05/30(土) 10:03:05.95ID:/LdiluDZ
2に3を足す時、
int a = 2; int b = 3; int c = a + b;
とやるとc == 5になる

int a = '2'; int b = '3'; int c = a + b;
とやってもc == '5'にはならない
今やほぼASCIIだからc == 'e'になる

int a = '2' - '0'; int b = '3' - '0'; int c = a + b;
とやるとc == 5になる
'0'から'9'まで連続していることはcの規格が強制してるから

これが”数字から'0'の番号を引き算すれば数値に変換され計算に使用できます”の意味
2020/05/30(土) 16:37:51.27ID:A5Abb6S3
char c = '8'; // '8'を表す文字コードの値(ASCIIでは56) char型
// '0' ... '0'を表す文字コードの値(ASCIIでは48) char型
// c - '0' ... '8'を表す文字コードから'0'を表す文字コードを引いた値(==8) char型
int a = c - '0'; // char型の数値8 で int変数a を初期化・代入

一般にint変数にchar型の値を格納することは認められている。


思うに「'8' - '0' が 8 になる」('8'の文字コードでなく「タダの8」)
という部分に引っ掛かってるんじゃなかろうか。
125124
垢版 |
2020/05/30(土) 16:49:13.96ID:A5Abb6S3
すまん 124 は間違ってるみたい、忘れてくれ。

char c = '8'; // '8'を表す文字コードの値(ASCIIでは56) char型
// '0' ... '0'を表す文字コードの値(ASCIIでは48) char型
// c - '0' ... '8'を表す文字コードから'0'を表す文字コードを引いた値(==8) int型
int a = c - '0'; // 数値8 で int変数a を初期化・代入

思うに「'8' - '0' が 8 になる」('8'の文字コードでなく「タダの8」)
という部分に引っ掛かってるんじゃなかろうか。


'8' - '0' は「char型の8」ではなく「int型の8」だね。(以下検証コード)
std::cout << "sizeof('8') == " << sizeof('8') << '\n';
std::cout << "sizeof('8'-'0') == " << sizeof('8'-'0') << '\n';
2020/05/30(土) 18:38:26.55ID:1Zwy+dfa
>>125
そういうことでしたか。
詳しく噛み砕いていただきありがとうございます。
127124
垢版 |
2020/05/30(土) 19:18:59.52ID:A5Abb6S3
型の検証はC++11なら直接的にできるね。

#include <typeinfo>
...
std::cout << "'8' is " << typeid('8').name() << '\n';
std::cout << "'8'-'0' is " << typeid('8'-'0').name() << '\n';

実装定義の型の名前を得られる。
128デフォルトの名無しさん
垢版 |
2020/06/05(金) 17:55:42.30ID:8OoEw/S/
なかなか、適当なスレを見付けるのが難しいわい
C++ 且つ初心者だから、ここでいいのかな

subroutine で、例えば、boolean と string のふたつの変数の値を
return するには、やっぱり std::map を使うのが一番簡単でしょうかね?
129デフォルトの名無しさん
垢版 |
2020/06/05(金) 18:21:06.88ID:Uv2w5eYU
std::pair<>じゃないのか?
https://ja.cppreference.com/w/cpp/utility/pair
130デフォルトの名無しさん
垢版 |
2020/06/05(金) 19:03:13.94ID:8OoEw/S/
うーん、なんとなくそうおもいます、ええ
131デフォルトの名無しさん
垢版 |
2020/06/05(金) 19:06:38.66ID:8OoEw/S/
あ、では、boolean, string, int の三つをreturn するには普通どうやるのが王道でしょうか?
132デフォルトの名無しさん
垢版 |
2020/06/05(金) 19:08:18.91ID:8OoEw/S/
連投すまん。
std::tuple ですか。
133デフォルトの名無しさん
垢版 |
2020/06/05(金) 19:12:47.23ID:Uv2w5eYU
たぶんそうだとお芋ます、ええ。
あと、コンテナに突っ込みたいときにはstd::variantなんかも良く使います。
今回は関係なさそうですが。
134デフォルトの名無しさん
垢版 |
2020/06/21(日) 13:29:09.07ID:hTPD8Gtd
>>131
王道かどうかは知らんが、C++17以降なら
auto func() {
return std::make_tuple(a, b, c);
}

auto [f, s, n] = func();
っていう風にできるで
135デフォルトの名無しさん
垢版 |
2020/06/21(日) 16:38:41.93ID:rRP2z2l8
std::tie の方が好き
2020/06/22(月) 16:40:35.96ID:sjaABjGh
C++でint[変数]というようなことが出来ないのはstack overflow防止のためなんでしょうか?
2020/06/22(月) 16:50:40.23ID:H8+bL0cM
>>136
原則として型は大きさが決まっているもんなので、そうでないものがあるとややこしいんだわ。
(配列の大きさは型の一部。)
2020/06/22(月) 20:24:27.49ID:83jG8pXe
Cの新しいのだと出来る
2020/06/22(月) 22:04:26.97ID:H8+bL0cM
>>138
新しいの……?

C99 で出来るようになったけど C11 以降ではオプショナル扱いなんだわ。
そして今年は 2020 年なんだわ。
2020/06/22(月) 23:23:01.67ID:rtw5aKlF
Cは89/90が基本
141デフォルトの名無しさん
垢版 |
2020/06/23(火) 01:32:00.34ID:UY2AjBBL
以下のコードは比較関数をSTLのlistに渡す為のものなのですが
これを最新のVC++でコンパイルできるようにするにはどう書き直せばいいでしょうか?

typedef SubType* LPSUBTYPE;

template<> inline bool greater<LPSUBTYPE>::operator()
(const LPSUBTYPE& pObj1, const LPSUBTYPE& pObj2) const {

}
2020/06/23(火) 09:26:35.36ID:RMSfHJVB
>>141
エラーメッセージを読んで問題点を解決するように書き直すといいよ。
list に比較関数は渡せないと思うので前提が間違ってそうな気もする。
2020/06/29(月) 08:08:09.53ID:PYBXxpGI
VC++についての質問になってしまうのですが、C#のようにソースファイルをリンクとして追加することは出来ないのでしょうか?
2020/06/29(月) 18:23:34.98ID:gWW+3u18
C#と違って「既存の項目」で追加したものに関してはコピーされずに参照扱いだよ
作業フォルダ下以外のファイルをそうやって追加した場合は追加のインクルードディレクトリも設定しないとダメだけど
2020/09/08(火) 02:57:29.22ID:ZBc9FXfY
何で構造体のchar配列は直接値が代入できず
strcpyを使う必要があるのでしょうか?
146デフォルトの名無しさん
垢版 |
2020/09/08(火) 03:20:04.77ID:jacy6RM2
できるよ
struct A {
int x;
char b[4];
} a = {0, 1, 2, 3, 4};
2020/09/08(火) 05:15:54.57ID:QZgDAT7o
>>146
それは代入ではなくて初期化
2020/09/08(火) 05:56:11.78ID:ZBc9FXfY
typedef struct {
char str[32];
}A;

int main(}{
A a;
a.str="aaa";
}

これができないってことです
言葉足らずですいません
149デフォルトの名無しさん
垢版 |
2020/09/08(火) 08:44:00.12ID:h4K4tlm9
int main(void) {
int arr[5];
arr = 3;
}

ができないのと同じ理由です
2020/09/08(火) 09:53:15.41ID:zoI9JNor
かわいいw
2020/09/08(火) 10:55:42.52ID:0vfIbeP0
ちょっと忘れたから、推測だけど、

a.str="aaa";

"aaa" を右辺で使うと、先頭要素のアドレスに変換されるとか?
例えば、4バイトのサイズで、10〜13 アドレスに存在する場合に、10が代入されるとか

char str[32];

一方、ここにはアドレスじゃなくて、aaa\0 という4バイトの実体を代入しないといけないとか
152デフォルトの名無しさん
垢版 |
2020/09/08(火) 11:16:05.69ID:h4K4tlm9
意図してるだろうことを無理してやるなら
str[0] = 'a';
str[1] = 'a';
str[2] = 'a';
str[3] = '\0';
でできる.そしてこれをするためにstrcopyがある
153デフォルトの名無しさん
垢版 |
2020/09/08(火) 15:36:44.61ID:JkCXGknl
>>148
型が違うし
2020/09/08(火) 15:57:15.69ID:SNM207t1
出来ない訳じゃないんだよな
typedef struct {
char b[4];
} A;

int main(void) {
A b = {1, 2, 3, 4};
A a;
a = b; // ok
a.b = b.b; // bad
return 0;
}
自分で for で配列要素代入すれば良い訳で
面倒だから memcpy や strcpy 使ってるだけ
155デフォルトの名無しさん
垢版 |
2020/09/08(火) 16:02:13.68ID:JkCXGknl
>何で構造体のchar配列は直接値が代入できず

構造体のchar配列だけじゃなくて
ただのchar配列でもダメだろ
宣言と同時に代入してるときはたまたま出来るだけ
int main() {
char a[4] = "abc"; // OK
char b[4];
b = "abc"; // BAD
return 0;
}
2020/09/09(水) 20:41:42.30ID:s+S5qxFe
>char a[4] = "abc"; // OK
これがおkなのは、cの言語仕様におけるほんの雀の涙猫の額ばかりの文字列サポート
たまたま、ってw
2020/09/09(水) 23:49:08.55ID:N/YnHGom
はじめたころは、こういうことにいちいちひっかかってたな…
わかっちゃえば、慣れちゃえばどーってことないんだけど
2020/09/10(木) 00:06:01.62ID:Qspm/kAl
同じようでいて、初期化と代入では見た目の作用がことなることがあるね
2020/09/10(木) 00:07:00.73ID:Qspm/kAl
見た目「と」作用が
2020/09/10(木) 15:36:27.72ID:rLZBXCmM
a も b も代入禁止だ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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