C++相談室 part141

■ このスレッドは過去ログ倉庫に格納されています
2019/02/22(金) 03:07:43.52ID:MgOIx7iK
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512

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

前スレ
C++相談室 part137 (正しくはpart138)
http://mevius.5ch.net/test/read.cgi/tech/1535353320/
C++相談室 part139
https://mevius.5ch.net/test/read.cgi/tech/1538755188/
C++相談室 part140
https://mevius.5ch.net/test/read.cgi/tech/1547326582/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.103【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1530384293/

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

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

----- テンプレ ここまで -----
-
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2019/03/06(水) 00:13:14.35ID:twKwvQwO
(1)か(2)を好みに応じて
2019/03/06(水) 00:17:08.38ID:URVwFrjm
特に何もないなら2

templateと組み合わせるなら1とか3は多用するけど4は無いな
215212
垢版 |
2019/03/06(水) 00:21:02.86ID:pU9AS85W
ありがとうございます
(2)でやってみることにします
2019/03/06(水) 00:32:13.90ID:Uli2bEJM
1 は、どうして君はすべての関数を、static 関数にできると思ったの?
static関数と、関数のライブラリ・モジュール化は関係ない

3, 4 は、どうして君は、関数を使うのにインスタンスが必要なの?

インスタンスの関数は、他の言語ではメソッドと言って、
そのインスタンスのメンバ変数を使うものに対して、特別な名称を付けている。
つまり、各インスタンスで値が異なるもの

メソッドは、一般的な関数とは異なる。
メソッドや一般的な関数と、関数のモジュール化は関係ない

例えば、Ruby では、
Math.log2( 8 ) #=> 3.0

このようにインスタンスを作らなくても、呼べる関数をモジュール関数と言って、
各インスタンスから呼ぶ関数を、メソッドと言って区別している
217212
垢版 |
2019/03/06(水) 00:42:25.73ID:pU9AS85W
そう言われるとそうですね
オブジェクト指向ではmain関数以外全部クラス/構造体で作成するものだという先入観がありました
2019/03/06(水) 01:06:06.33ID:Riy5qgFP
>>214
無理矢理4にしたいケースを考えると、同じインターフェースを持つ関数群A,Bを場合によって切り替えて使いたい場合に敢えてインスタンスのポインタとすることもあるかな。今回の質問者の場合には当てはまらないだろうけど。
2019/03/06(水) 01:10:14.42ID:MDLmYlCa
>>193
>1つのcppの中でしか使わず外に見せないクラスや関数はcppの中でいいよ
名前無しでも何でも良いが、その場合はクラスはnamespaceの中に入れないと危険が危なすぐる…

同じ名前空間に属する同じシグネチャのFoo::func()が異なる関数として複数のcppで定義された場合、
どっちが呼ばれるか定まらない処理系が実在する(VC++2010とか
多分ODR違反で未定義動作なんだと思う
2019/03/06(水) 01:13:13.20ID:paKD8ls/
曖昧さは、利点にも欠点にもなりうる。
namespaceのグローバル関数ではなくクラスのスタティック関数にすることで曖昧さがなくなりコンパイルエラーを避けられる場合がある。
2019/03/06(水) 01:14:08.29ID:MDLmYlCa
>>219訂正
CPPでクラスを定義する場合は無名namespaceに入れないと危険が危なすぐる、
無名namespaceは異なる翻訳単位間では別名として扱われるから安全

一方、名前付きnamespaceでは異なるCPPで偶然
同じ名前空間に属する同じシグネチャのFoo::func()が作られてしまう危険性を排除できない
2019/03/06(水) 01:21:31.24ID:MDLmYlCa
>>220
そのクラスに非staticなメソッドを設けたとたん、
>>219と同じ話でどのFoo::func()が呼ばれるかわからないという不正な動作をする危険性が生じる

驚くべきことに、VC++2010の場合リンカが何のエラーも警告も出さない
それでいてしっかり変な動作になる(a.cppで定義したFoo::func()を呼んだつもりがb.cppで定義された同じシグネチャの別のFoo:func()が呼ばれる
223KAC
垢版 |
2019/03/06(水) 01:53:40.57ID:tePy6oFI
>>216
C/C++では、staticなどキーワードが全く違う複数の意味で使われるから注意な。
224216
垢版 |
2019/03/06(水) 02:00:53.56ID:Uli2bEJM
Ruby では、関数名のバッティングを避けるため、2重に囲む。
module 内にclass か、class内にclassを作る

module Net
class HTTP end
class FTP end
end

# インスタンス
Net::HTTP.new
Net::FTP.new
2019/03/06(水) 02:06:24.72ID:Riy5qgFP
>>224
rubyボットはお呼びでないからもう巣に帰ってくれ
226216
垢版 |
2019/03/06(水) 02:12:57.91ID:Uli2bEJM
static みたいな複雑な概念を、初心者が理解するのは難しい

スコープを限定する意味と、生成・破壊のタイミングの違いと、
2つの異なる概念を使うから、難しい

C++ は、すべてのリソースの生成・破壊のタイミングを追っかけるだけでも、大変

ドワンゴ江添の本「C++11/14 コア言語」にも書いてあるけど、

呼ばれる関数を探索する方法に、Andrew Koenig が提案した、実引数依存の名前探索 (ADL)もある

実引数依存の名前探索とは、C++において関数呼出時に与えられた引数の型に依存して、
呼び出す関数を探索 (lookup)する仕組みのことである。
英語ではKoenig lookup、argument dependent lookup (ADL)、argument dependent name lookupなどと呼ばれる
2019/03/06(水) 02:46:55.34ID:Riy5qgFP
>>216
>>212の(1)はクラスのstaticメンバ関数のことを言っているのだか、>>216>>226を見てるとそれを理解していないように思える。
いつも書籍や他人の発言を引用して〜〜では、という書き方ばかりしているのを見かけるが、自分の中に落とし込んで理解できてないならわざわざ書き込まないでくれ。
2019/03/06(水) 04:34:02.55ID:3uIPjLtJ
>>227
#激同
2019/03/06(水) 06:59:23.47ID:3Q0pfzsC
質問(ネタ振り)に対して見当違いな返答は混乱の元ってのはその通りとして。
読者の立場では、話題が広がってくのは嫌いじゃない。

投稿者の意見として消化しきれてなくても、
参考資料として「誰それの書いたナントカって本では…」と
紹介してくれるのも有難いし。

その上で「あの著者/本は間違いが多い、例えば…」とか、
「記述が古い、新しい規格でもっと便利な機能が追加された」みたいな
追加情報(具体的なもの)が出てくればなお嬉しい。
230デフォルトの名無しさん
垢版 |
2019/03/06(水) 09:56:40.41ID:mg6kC0Yg
>>205
SQLの話ですか(苦笑)
2019/03/06(水) 18:18:48.94ID:paKD8ls/
名前なし名前空間を名前あり名前空間の中に作ることができる。便利ちゃあ便利。

namespace hoge {
namespace {
int foobar = 1;
};
};
232デフォルトの名無しさん
垢版 |
2019/03/06(水) 21:53:00.33ID:paKD8ls/
64bit環境で文字列ストリームクラスstd::ostringstreamのインスタンスのスタックサイズが、
gccで376バイト, VS2017で232バイトもあるんだがもっと小さくできるんじゃないの?
ちなみに、std::string はgccとVS2017どちらも32バイト。
どうよ?
2019/03/06(水) 22:13:52.26ID:7/fqDaVy
>>232
std::ostringstream は文字列の一種というよりも入出力の系統だし、
std::basic_ostream を抱えているのでそんなもんちゃう?
2019/03/06(水) 22:36:11.10ID:cpQrrMgl
継承してるしデータとして保持しておくものでもないしな
2019/03/06(水) 23:24:49.53ID:TjQtzcPT
>>232
質問と関係ないけどスタックサイズって何かわかってないだろ
2019/03/07(木) 01:12:44.42ID:FDOfvyow
このあとスタックがおいしくいただきました
237デフォルトの名無しさん
垢版 |
2019/03/07(木) 01:36:59.97ID:7rstSYcJ
ostream, ofstream, ostringstreamのスタックサイズはgccとVS2017でそれぞれ以下のようになる。
gcc: ostream=112, ofstream=264, ostringstream=232
VS2017: ostream=272, ofstream=512 ostringstream=376

どうよ?
238237
垢版 |
2019/03/07(木) 01:39:26.14ID:7rstSYcJ
間違えた。gccとVS2017は逆です。
何が言いたいというと、組み込みで気軽に使えるC++を目指すならiostream周りを何とかしないとね、という話。
2019/03/07(木) 01:41:48.62ID:1uoKMGSD
組み込みで気軽に使えるC++を目指してないしどこまで削れるかはベンダーの努力次第
240237
垢版 |
2019/03/07(木) 01:45:06.81ID:7rstSYcJ
Cがコンパイル言語であるにもかかわらずprintf()系の構文解析でJITコンパイルする野暮ったさを解決すべく導入されたはずのiostreamがまったく活かされていないね。
2019/03/07(木) 01:45:09.29ID:E2AqWV/D
その程度のスタック消費でヒーヒー言うような組み込み案件でiostream使わんだろ
242237
垢版 |
2019/03/07(木) 01:49:48.32ID:7rstSYcJ
>>241
スタック消費でヒーハー言う組み込み案件に進出するのもC++のひとつの課題なのでは有馬温泉
2019/03/07(木) 01:52:03.09ID:1uoKMGSD
組み込み界隈がC++を活用する目標があるのであってC++の目標ではない
2019/03/07(木) 01:56:44.60ID:E2AqWV/D
from_chars
to_chars使えって話だろ

それかfmt
245デフォルトの名無しさん
垢版 |
2019/03/07(木) 03:10:47.55ID:V0jGdMU/
class C : public std::function<int(int)>{};

というクラスを定義して、

int f(int i){ return i + 1; }

void main()
{
C c = f;
int i = c(1);
}

みたいな使い方って出来ないのでしょうか?
functional のヘッダを読んでみましたがさっぱりでした
2019/03/07(木) 03:21:15.84ID:fFrTWbSf
>>245
やりたいのはこういうこと?

class C : public std::function<int(int)>{
using std::function<int(int)>::function;
};
2019/03/07(木) 03:25:38.52ID:fFrTWbSf
めっちゃ雑にやったけど、
実際にはスライシングに気を付けてな。
2019/03/07(木) 03:42:38.23ID:V0jGdMU/
>>246
すいません、
知識不足でそのusingが何を意味しているのか分かりませんが、
std::function<int(int)> と、
class C : public std::function<int(int)>{} を、
外側から同じように使いたいという感じです。

現在は、
class C { std::function<int(int)> F; };
みたいになっており、

C c;
c.F = f;
int i = c.F(1);

と、こんな風に使われています。
std::function<int(int)> を継承させてしまい、.Fを消したい感じです。
2019/03/07(木) 04:00:06.05ID:fFrTWbSf
>>248
単純に

class C : public std::function<int(int)>{}

とした場合、当然だけどクラス C にデフォルトで定義されるコンストラクタは
C::C(void); と C::C(const C&); だから、型が int (*)(int) であるような値を受け取る余地はない。

using std::function<int(int)>::function;

を入れると基底クラス std::function<int(int)> のコンストラクタである
std::function<int(int)>::function; をあたかも C のコンストラクタみたいにできる。
そんだけ。
public 継承してれば std::function<int(int)> の他のメンバはそのまま C のメンバとして
見えるからおおよそ期待する挙動になると思う。
2019/03/07(木) 04:06:09.21ID:V0jGdMU/
>>249
なるほど、そういう意味だったのですね。
ちょっと試してみます。ありがとうございます。
2019/03/07(木) 08:20:27.58ID:Yz7Qf/Kl
>>237
2ファイル同時に編集なんてしたらあっという間に食い潰しそうね
252デフォルトの名無しさん
垢版 |
2019/03/08(金) 01:15:31.98ID:jsJl1WSX
テンプレートで何とかなりませんかね。
2019/03/08(金) 02:12:42.20ID:7lrcs+kH
>>252
何が?
254237
垢版 |
2019/03/08(金) 06:55:44.25ID:orP5LHkV
>>244 が提示してくれた from_chars, to_chars をgccに導入するにはどうしたらいい?
WSLのubuntuを使ってるんだけど規定でfrom_chars, to_charsの定義されたヘッダーファイルが入ってないっぽい。
2019/03/08(金) 08:26:54.11ID:ZyNdKvhR
>>254
たしか8.0でまだ整数しか実装されてない
256デフォルトの名無しさん
垢版 |
2019/03/09(土) 11:07:13.09ID:jx9iLAiD
C++テンプレートテクニック第三版っていつ出るんですかね?
2019/03/10(日) 00:54:12.40ID:3tC9wBDx
待っていても何も始まらない!
君が書くんだよ!
258デフォルトの名無しさん
垢版 |
2019/03/10(日) 17:07:48.90ID:yzd/Af8M
テンプレート引数がクラスでpush_back()メンバを持っているというようなことを検査することはできますかね?
2019/03/10(日) 17:10:17.73ID:2Qm7LFrM
std::is_classとdetection idiomで可能かと
260デフォルトの名無しさん
垢版 |
2019/03/10(日) 17:15:14.74ID:yzd/Af8M
でてくしょんいでおむってどの本見ればわかりますかね?
261デフォルトの名無しさん
垢版 |
2019/03/10(日) 17:16:33.87ID:yzd/Af8M
decltype使えばいいのかな。
2019/03/10(日) 17:18:14.94ID:2Qm7LFrM
載ってる本あるのかなあ

どうやるのかだけなら、ここのサンプルコードを真似すればいいと思う
https://cpprefjp.github.io/reference/type_traits/void_t.html
263デフォルトの名無しさん
垢版 |
2019/03/10(日) 17:21:49.62ID:yzd/Af8M
ありがとう。
ちょっと読んでみます。
264デフォルトの名無しさん
垢版 |
2019/03/10(日) 22:01:07.26ID:yzd/Af8M
std::byteの使い方がよくわからない。
暗黙の何とかを避けるのに使うんだろか。
2019/03/10(日) 22:11:27.82ID:2Qm7LFrM
単純にバイトを表現する型というのが必要となった
char8_tと同じようなもん
266デフォルトの名無しさん
垢版 |
2019/03/10(日) 22:30:00.78ID:yzd/Af8M
ソケットやファイルの入出力に使うって事かな?
2019/03/10(日) 22:49:36.48ID:8hqMg5Px
1バイトサイズの整数のつもりでcharを使ったらstreamで困ることがあったりしたしね。
268デフォルトの名無しさん
垢版 |
2019/03/10(日) 23:15:04.53ID:yzd/Af8M
enum class byte : unsigned char { };
ってなってる。
2019/03/10(日) 23:21:10.96ID:6gF9+EwK
そのベースの型は実装依存
型を取りだして使えってことなんだろうか
2019/03/10(日) 23:21:22.34ID:ketqiw2j
なんでenum classなんだ?
typedefと何が違うの?
2019/03/10(日) 23:31:19.81ID:2Qm7LFrM
暗黙の型変換ができない
2019/03/10(日) 23:54:49.98ID:vvRzWHgY
こういうの行き過ぎた型安全に思えるけどね
2019/03/10(日) 23:57:35.21ID:6gF9+EwK
でも過去にそれで何かあったんでしょ
使うかどうかは任意だしある分には困らない
2019/03/10(日) 23:57:38.91ID:ketqiw2j
なるほど
2019/03/11(月) 00:01:39.15ID:4nU22VRt
is_enum_vがtrueになるとか違和感しかない
276デフォルトの名無しさん
垢版 |
2019/03/11(月) 05:30:01.20ID:pTTv+VC9
>>265
なんで
uchar8_t
uchar16_t
uchar32_t
にしないんだろな
2019/03/11(月) 05:58:05.15ID:mFqdzmI2
既存のライブラリと衝突しまくるだろそれ
2019/03/11(月) 11:02:11.57ID:9rO3q8tQ
>>273
ひとりで全部作ってんのか?
誰か使い始めたらそれに巻き込まれるんだよ
2019/03/11(月) 13:49:05.84ID:kWR5MawD
WPFってどうなの
2019/03/11(月) 19:42:26.86ID:OenRxSRY
281デフォルトの名無しさん
垢版 |
2019/03/11(月) 22:05:24.43ID:XA5PtgcF
getoptの標準化マダーチンチン(AA略
2019/03/12(火) 07:17:28.89ID:dEFL2K0T
void foo(std::function<void()> &&f){}

int main(){
auto lamda = [](){};
foo(lamda);
}
なぜコンパイルできるの?
283デフォルトの名無しさん
垢版 |
2019/03/12(火) 07:23:08.39ID:FSVt1tPQ
>>281
オプションの渡し方がそもそも揺れてる
284デフォルトの名無しさん
垢版 |
2019/03/12(火) 07:25:00.12ID:FSVt1tPQ
>>282
int main()
{
return main();
}
なぜコンパイルできるの?
285デフォルトの名無しさん
垢版 |
2019/03/12(火) 11:46:00.90ID:6Uu2j9Xc
int main(std::function<void()> &&f){
return main([](){});
}
2019/03/12(火) 20:22:26.93ID:dEFL2K0T
すいません、低レベルのかたたちばかりでした。
聞くところ間違えました
2019/03/12(火) 20:30:56.16ID:Nd0ou12Q
なぜc++ main return省略でググらないのか
288デフォルトの名無しさん
垢版 |
2019/03/12(火) 20:43:58.42ID:X3QnQcuN
getoptを標準化してしまうとハイフンで始まる変態ファイル名が鬼門になってしまうかな。
289デフォルトの名無しさん
垢版 |
2019/03/12(火) 20:46:35.39ID:Zu3OGTTs
is_iterator、is_containerメタ関数はどうやったら作れるんでしょうね?
2019/03/12(火) 20:54:07.45ID:JuWddRAo
SFINAEでググれ、でいいんだろうか
291デフォルトの名無しさん
垢版 |
2019/03/12(火) 20:55:53.60ID:Zu3OGTTs
スフィ姉は知っているんですが。
そのあとが。
2019/03/12(火) 21:00:20.04ID:cgm/opRe
iterator_traitsに通してメンバ型が得られるか確認する?
*とか++とかの操作について確認する?
containerはbeginとendでイテレータ取れるか確認する?
293デフォルトの名無しさん
垢版 |
2019/03/12(火) 21:34:26.86ID:Zu3OGTTs
template <typename T>
using is_iterator = std::is_class<typename std::iterator_traits<T>::iterator_category>;
これは使えますかね?
2019/03/12(火) 21:58:48.29ID:l3wdXFC4
ぐぐればstack overflowがひっかかる
2019/03/12(火) 22:01:23.70ID:JuWddRAo
使えますかねって・・自分で試せるだろ
2019/03/12(火) 22:12:53.32ID:6dDI1fa3
マウントしててワロス
2019/03/12(火) 22:34:48.05ID:3laDxwEs
マウントは取りたいけど教えるのはめんどくさい
2019/03/12(火) 22:48:31.61ID:YKaKEG7g
結局はそれで何がしたいかによるんじゃね
標準のコンテナやそのイテレータで型分岐したいなら十分だけど、カスタム実装されたユーザー定義のイテレータがそのように実装されているかは分からんし
まあiterator_traitsの特殊化も追加で書くようにすれば使えるか
2019/03/12(火) 23:06:42.78ID:cgm/opRe
C++20からは一応イテレータはコンセプトがあるなあ
コンテナは知らん
2019/03/12(火) 23:12:51.59ID:YKaKEG7g
>>293
はダメな気がするな
template<typename T,typename=void>
struct is_iterator:std::false_type{};

template<typename T>
struct is_iterator<T,std::enable_if_v<std::is_class_v<typename std::iterator_traits<T>::iterator_category>>>:std::true_type{};
2019/03/12(火) 23:14:38.07ID:JuWddRAo
>>296,297
アホか、何がマウントだボケ
自分で試しもせずに2chに丸投げとか普通にダメだろ

>>298
iterator_traitsに与える型の要件(だけでいいかどうかはさておき)を満たすなら特殊化なんかいらんでしょ
リファレンス見る限り、iterator_traitsの特殊化はポインタのためだけにあると思う
302デフォルトの名無しさん
垢版 |
2019/03/12(火) 23:27:20.69ID:Zu3OGTTs
>>300
どの本もそういう書き方になってるんだけど、その理由がわからない。
>>293は呼び出し方によっていろいろ問題が起きるんだけど、その理由がわからなさすぎる。
その辺がスッキリわかる本はないですかね。
2019/03/12(火) 23:39:14.10ID:YKaKEG7g
本は知らん
SFINAEが使えるのは宣言部分
そこで置換失敗すると宣言そのものが無かったことになる
2019/03/13(水) 12:04:15.67ID:lxBl+sTZ
>>297
マウントが取りたいだけで教える知識がないだけやねんw
2019/03/13(水) 12:37:00.35ID:mh4jyrHE
そう
分からない質問には自分で試せ
これがC++使ってる奴の特徴
2019/03/13(水) 12:47:27.60ID:QLyGxm6u
>>304,>>305
そう思うなら自分が教えてやれば?
2019/03/13(水) 20:50:37.56ID:u/DrurAb
規約はあるけど「実装が規約」をやっちゃってる部分が多くて、
しかもコンパイラのバージョン依存がひどいってのがc++だからな。
規約は語れても実際にどう動作するか語れない輩も多いだろうね。
2019/03/13(水) 21:07:13.50ID:QLyGxm6u
そういう構図じゃないと思うよ
309デフォルトの名無しさん
垢版 |
2019/03/13(水) 21:25:53.81ID:Z/ka/TFK
どなたか iostreamの存在価値について熱く語ってくれないか。
2019/03/13(水) 21:34:23.99ID:VRJ3bLEu
いやだ
2019/03/13(水) 21:38:23.77ID:xQTh8hgU
>>309
https://www.google.com/search?q=%22iostream%E3%81%AE%E4%BE%A1%E5%80%A4%22
312デフォルトの名無しさん
垢版 |
2019/03/13(水) 21:55:23.80ID:780qHyAl
VS2019って4月2日に出るのかな?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。