前スレ
C++相談室 part157
https://mevius.5ch.net/test/read.cgi/tech/1628474251/
探検
C++相談室 part158
■ このスレッドは過去ログ倉庫に格納されています
2021/11/15(月) 18:49:18.44ID:I69rZ/Of
758デフォルトの名無しさん
2022/01/31(月) 20:55:29.83ID:ExACmeMg >>753
auto Sum = [](auto head, auto... rests) { return (head + ... + rests); };
auto Sum = [](auto head, auto... rests) { return (head + ... + rests); };
759デフォルトの名無しさん
2022/01/31(月) 22:50:37.06ID:67CF9RIT ラッパークラスを通せば似たようなことはできそう。
struct Wrapper_ {
constexpr static auto doit = [](auto... args) { return Sum(args...); };
} wrapper;
int main( int, char ** )
{
std::cout << foo(wrapper.doit,1,2,3) << "\n";
}
struct Wrapper_ {
constexpr static auto doit = [](auto... args) { return Sum(args...); };
} wrapper;
int main( int, char ** )
{
std::cout << foo(wrapper.doit,1,2,3) << "\n";
}
760デフォルトの名無しさん
2022/02/01(火) 04:38:50.89ID:X9o0BiPI クラスは不要だった。
ラムダなら通るみたいだから、 >>758 みたいに元の関数をラムダで書くか、
auto wrapper = [](auto... args) { return Sum(args...); };
みたいなラッパー関数オブジェクト通すかってあたりで足りそう。
// 最初実験してたとき、ラムダ式にしただけだとエラー出てた気がしたんだけど、今やると問題なく通る…
ラムダなら通るみたいだから、 >>758 みたいに元の関数をラムダで書くか、
auto wrapper = [](auto... args) { return Sum(args...); };
みたいなラッパー関数オブジェクト通すかってあたりで足りそう。
// 最初実験してたとき、ラムダ式にしただけだとエラー出てた気がしたんだけど、今やると問題なく通る…
761デフォルトの名無しさん
2022/02/01(火) 05:38:09.33ID:wGiSz27Y おお、auto... なんてできたのか
762デフォルトの名無しさん
2022/02/01(火) 07:53:40.48ID:vPA4cgbg >>757にラムダ入れた。
ラムダはオーバーロードできずC++17の畳み込み式が必須で引数なしが表現できないが、選択の手間がない。
#include <iostream>
auto sum() {return 0;}
template<typename Head> auto sum(Head head) {return head;}
template<typename Head, typename... Tails> auto sum(Head head, Tails ...tails) {return head + sum(tails...);}
template<typename Return, typename... Args> Return wrap(Return (*f)(Args...), Args ...args) {return f(args...);}
auto lambda_sum = [](auto head, auto ...tails) {return (head + ... + tails);}; // 追加
auto lambda_wrap = [](auto f, auto ...args) {return f(args...);}; // 追加
int main( int argc, char *argv[] ) {
std::cout << sum() << std::endl; // 追加
std::cout << sum(1) << std::endl; // 追加
std::cout << sum(1,2.1) << std::endl;
std::cout << wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << wrap(sum, 1,2.1) << std::endl; // エラー
// lambda版追加
// std::cout << lambda_sum() << std::endl; // エラー
std::cout << lambda_sum(1) << std::endl; // 追加
std::cout << lambda_sum(1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(lambda_sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << lambda_wrap(lambda_sum<int,double>, 1,2.1) << std::endl; // not template
// std::cout << lambda_wrap(sum, 1,2.1) << std::endl; // エラー
std::cout << lambda_wrap(lambda_sum, 1,2.1) << std::endl;
return 0;
}
ラムダはオーバーロードできずC++17の畳み込み式が必須で引数なしが表現できないが、選択の手間がない。
#include <iostream>
auto sum() {return 0;}
template<typename Head> auto sum(Head head) {return head;}
template<typename Head, typename... Tails> auto sum(Head head, Tails ...tails) {return head + sum(tails...);}
template<typename Return, typename... Args> Return wrap(Return (*f)(Args...), Args ...args) {return f(args...);}
auto lambda_sum = [](auto head, auto ...tails) {return (head + ... + tails);}; // 追加
auto lambda_wrap = [](auto f, auto ...args) {return f(args...);}; // 追加
int main( int argc, char *argv[] ) {
std::cout << sum() << std::endl; // 追加
std::cout << sum(1) << std::endl; // 追加
std::cout << sum(1,2.1) << std::endl;
std::cout << wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << wrap(sum, 1,2.1) << std::endl; // エラー
// lambda版追加
// std::cout << lambda_sum() << std::endl; // エラー
std::cout << lambda_sum(1) << std::endl; // 追加
std::cout << lambda_sum(1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(static_cast<double(*)(int,double)>(lambda_sum), 1,2.1) << std::endl;
std::cout << lambda_wrap(sum<int,double>, 1,2.1) << std::endl;
// std::cout << lambda_wrap(lambda_sum<int,double>, 1,2.1) << std::endl; // not template
// std::cout << lambda_wrap(sum, 1,2.1) << std::endl; // エラー
std::cout << lambda_wrap(lambda_sum, 1,2.1) << std::endl;
return 0;
}
763デフォルトの名無しさん
2022/02/01(火) 22:23:26.64ID:rdLB3H0G c++では
sz=120;
char dt[sz];
このように配列のサイズを変数の可変サイズで指定することはできないんですか?
これを実現する方法は何かありませんか?
sz=120;
char dt[sz];
このように配列のサイズを変数の可変サイズで指定することはできないんですか?
これを実現する方法は何かありませんか?
764デフォルトの名無しさん
2022/02/01(火) 22:43:02.67ID:rdLB3H0G 自己解決しました
しかし dt[10][d] のように2次元以上はjavaのような動的変動はできないんですね
しかし dt[10][d] のように2次元以上はjavaのような動的変動はできないんですね
765デフォルトの名無しさん
2022/02/01(火) 23:27:31.22ID:fhOfpvRh vector使わんの?
766デフォルトの名無しさん
2022/02/01(火) 23:28:28.99ID:hJiWfYJV 配列使わんし
767デフォルトの名無しさん
2022/02/01(火) 23:30:45.06ID:Sh1zYLGa768デフォルトの名無しさん
2022/02/02(水) 10:03:42.12ID:pPu7Tazo コンストラクタ・テンプレートでテンプレート実引数を推定させず明示的に与えるのはどう書く?
struct some_class
{
template <class A> some_class(int) {}
};
int main()
{
some_class obj<void>(1); //error
}
struct some_class
{
template <class A> some_class(int) {}
};
int main()
{
some_class obj<void>(1); //error
}
769デフォルトの名無しさん
2022/02/02(水) 12:11:02.47ID:ryNE78sg >>768
コンストラクタには明示的に型引数を渡せない
コンストラクタには明示的に型引数を渡せない
770デフォルトの名無しさん
2022/02/02(水) 12:36:54.65ID:pPu7Tazo そっか。。。残念
thx >>769
thx >>769
771デフォルトの名無しさん
2022/02/02(水) 12:56:51.10ID:X/91R13x ファイルサイズを取得しようとしていろいろサイトを参考にして次のようにしたのですが
std::filesystem::file_size(path)
filesystemのところに赤線が出て使用できません
これらは記述しています
#include <iostream>
#include <fstream>
#include <filesystem>
使っているのはCommunity 2019です
filesystemが使えないのはなぜでしょう?
std::filesystem::file_size(path)
filesystemのところに赤線が出て使用できません
これらは記述しています
#include <iostream>
#include <fstream>
#include <filesystem>
使っているのはCommunity 2019です
filesystemが使えないのはなぜでしょう?
772デフォルトの名無しさん
2022/02/02(水) 13:02:34.63ID:ryNE78sg773デフォルトの名無しさん
2022/02/02(水) 13:34:32.24ID:pPu7Tazo >>771
/std:c++17は指定してる?
/std:c++17は指定してる?
774デフォルトの名無しさん
2022/02/02(水) 13:43:30.57ID:X/91R13x ありがとうございます C++17指定できました
775デフォルトの名無しさん
2022/02/03(木) 12:49:10.84ID:d1XPVqCl filesystemは、できればC++20モードで使いたい
file_clockまわりがC++17ではgdgdだから
file_clockまわりがC++17ではgdgdだから
776デフォルトの名無しさん
2022/02/04(金) 13:06:35.94ID:ovGR74Kw 小文字に変換するプログラムです
string toLowerCase(const string& str)
{
string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(), std::tolower);
return lower;
}
実行するとstd::transform 一致するオーバーロードする関数が見つかりません、とか
6引数が必要です 4が設定されてます、とか出て
実行できません
これは何が問題なのでしょうか?
string toLowerCase(const string& str)
{
string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(), std::tolower);
return lower;
}
実行するとstd::transform 一致するオーバーロードする関数が見つかりません、とか
6引数が必要です 4が設定されてます、とか出て
実行できません
これは何が問題なのでしょうか?
777デフォルトの名無しさん
2022/02/04(金) 13:07:58.25ID:N/NFryku tolowerが多重定義関数だからじゃね?
778デフォルトの名無しさん
2022/02/04(金) 13:22:13.60ID:ovGR74Kw 自分では他に定義してないんですがどこで定義されてるんでしょう
779はちみつ餃子 ◆8X2XSCHEME
2022/02/04(金) 13:28:07.50ID:RpLWwySn >>776
ちょうど >>658 で同じような事例が出ている。
std::tolower は cctype ヘッダと locale ヘッダにそれぞれあって
locale ヘッダのほうが関数テンプレートだし二引数なのでこの場の都合に合わない。
なんらかの方法でどれを使うのか選択する必要があり、
たとえば static_cast などが使える。
ただ、 >>661 が提示しているようにデフォルト引数が追加される可能性があったりもするので
static_cast よりはラムダ式を経由するほうが安心できるスタイルかもね。
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string toLowerCase(const std::string& str)
{
std::string lower;
std::transform(std::begin(str), std::end(str), std::back_inserter(lower), static_cast<int(*)(int)>(std::tolower));
return lower;
}
int main(void) {
std::cout << toLowerCase("abcDEfgHi") << std::endl;
}
ちょうど >>658 で同じような事例が出ている。
std::tolower は cctype ヘッダと locale ヘッダにそれぞれあって
locale ヘッダのほうが関数テンプレートだし二引数なのでこの場の都合に合わない。
なんらかの方法でどれを使うのか選択する必要があり、
たとえば static_cast などが使える。
ただ、 >>661 が提示しているようにデフォルト引数が追加される可能性があったりもするので
static_cast よりはラムダ式を経由するほうが安心できるスタイルかもね。
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string toLowerCase(const std::string& str)
{
std::string lower;
std::transform(std::begin(str), std::end(str), std::back_inserter(lower), static_cast<int(*)(int)>(std::tolower));
return lower;
}
int main(void) {
std::cout << toLowerCase("abcDEfgHi") << std::endl;
}
780デフォルトの名無しさん
2022/02/04(金) 13:35:40.02ID:ovGR74Kw ありがとうございます ビルド通ったみたいです
781デフォルトの名無しさん
2022/02/04(金) 13:55:24.36ID:3M0ClPfa 最近のはptr_funやんなくても通んだな
782デフォルトの名無しさん
2022/02/05(土) 11:50:25.88ID:DOE5sh/+ template<yyy T>//yyyはコンセプト
requires !xxx<T>//xxxはコンセプト
void test(const T& a);//yyyのコンセプトを満たしxxxのコンセプトを満たさないものについて処理したい
C++20のコンセプトのrequires節って!使うと警告出るのでわざわざ否定用のコンセプト作成して対応してるんだけど、もっと簡単な仕組みない?
requires !xxx<T>//xxxはコンセプト
void test(const T& a);//yyyのコンセプトを満たしxxxのコンセプトを満たさないものについて処理したい
C++20のコンセプトのrequires節って!使うと警告出るのでわざわざ否定用のコンセプト作成して対応してるんだけど、もっと簡単な仕組みない?
783デフォルトの名無しさん
2022/02/05(土) 11:52:48.48ID:vpksE3yJ requires (!xxx<T>)
784デフォルトの名無しさん
2022/02/05(土) 12:04:00.17ID:DOE5sh/+ 解決した!ありがとう!
785デフォルトの名無しさん
2022/02/05(土) 20:23:31.04ID:Irrrknzv #define FOO() 1
#if FOO
...
#endif
と書いた場合FOOの後ろに()付けるの忘れてるのでコンパイルエラーになって欲しいんですが
実際はFOOは偽に評価されてるみたいです
何が起きてるんでしょうか?
#if FOO
...
#endif
と書いた場合FOOの後ろに()付けるの忘れてるのでコンパイルエラーになって欲しいんですが
実際はFOOは偽に評価されてるみたいです
何が起きてるんでしょうか?
786はちみつ餃子 ◆8X2XSCHEME
2022/02/05(土) 20:31:08.99ID:NEwj3nV7 >>785
#if の条件の部分ではマクロ展開できるものを全部展開したあとに知らない識別子が残ったら 0 と解釈する。
#if の条件の部分ではマクロ展開できるものを全部展開したあとに知らない識別子が残ったら 0 と解釈する。
787デフォルトの名無しさん
2022/02/05(土) 20:32:57.42ID:BHACckaU >>785
FOO に () が無いことで展開されず、マクロ展開後に残った識別子として 0 に置き換わってる。
https://timsong-cpp.github.io/cppwp/n4868/cpp.cond#11.sentence-1
> After all replacements ..., all remaining identifiers and keywords,
> except for true and false, are replaced with the pp-number 0, ...
FOO に () が無いことで展開されず、マクロ展開後に残った識別子として 0 に置き換わってる。
https://timsong-cpp.github.io/cppwp/n4868/cpp.cond#11.sentence-1
> After all replacements ..., all remaining identifiers and keywords,
> except for true and false, are replaced with the pp-number 0, ...
788デフォルトの名無しさん
2022/02/06(日) 01:29:50.60ID:Yc7Iwiyd >>785
バカですか?
バカですか?
789デフォルトの名無しさん
2022/02/06(日) 01:32:54.82ID:3BxbnhGH #if defined(FOO)
...
#endif
...
#endif
790デフォルトの名無しさん
2022/02/06(日) 01:34:05.59ID:Yc7Iwiyd Cの基本が出来てないくせにC++を使いこなせると思うなよ
791デフォルトの名無しさん
2022/02/06(日) 01:35:00.88ID:H2F64OwB 横からだけど知らなかった
792デフォルトの名無しさん
2022/02/06(日) 03:28:00.08ID:XnD7OQcd793デフォルトの名無しさん
2022/02/06(日) 06:46:34.29ID:qvD4QsX7 こういう馬鹿のためにコンパイラに無駄なルールが必要になるんだなと実感
794デフォルトの名無しさん
2022/02/06(日) 06:55:06.64ID:usxBX4wT エラーにならないのは理不尽だな
795デフォルトの名無しさん
2022/02/06(日) 08:23:12.41ID:qvD4QsX7 馬鹿のためにわざわざプリプロセスで構文解析エラーを要求するとか馬鹿の極み
796デフォルトの名無しさん
2022/02/06(日) 08:30:29.95ID:usxBX4wT FOOが0になる根拠を与えていないだろ
関連付けられていないものが出てくるのがおかしいと思わないとしたらPG適性低いぞ
関連付けられていないものが出てくるのがおかしいと思わないとしたらPG適性低いぞ
797デフォルトの名無しさん
2022/02/06(日) 08:53:46.75ID:2YxKeDPZ 唐突に0がどうとか言い出すのはセンス無いわ
798デフォルトの名無しさん
2022/02/06(日) 09:07:44.45ID:HE5J2RYG 初めて知った
799デフォルトの名無しさん
2022/02/06(日) 09:24:54.74ID:usxBX4wT800デフォルトの名無しさん
2022/02/06(日) 09:35:58.81ID:qvD4QsX7 馬鹿は当たり前のように英語も読めない
801デフォルトの名無しさん
2022/02/06(日) 09:36:22.76ID:vWDceL4H なんじゃそりゃ>>799はC++規格委員会が死ね言うたら死ぬんか、
802デフォルトの名無しさん
2022/02/06(日) 09:57:50.12ID:vWDceL4H 規格書にはなんでそうなっているのか(置換されずに残ったFOOをエラーではなく0にするのか)の理由が書かれていないが
#ifdef defined(FOO) && FOO
として現れる論理式「defined(FOO) && FOO」の解釈を簡単にやりたい(FOOが未定義の場合でも通常の式の解釈ルーチンで処理したい
的なしょーもない理由だったりして……
#ifdef defined(FOO) && FOO
として現れる論理式「defined(FOO) && FOO」の解釈を簡単にやりたい(FOOが未定義の場合でも通常の式の解釈ルーチンで処理したい
的なしょーもない理由だったりして……
803デフォルトの名無しさん
2022/02/06(日) 09:59:13.49ID:vWDceL4H まつがえたorz
×: #ifdef defined(FOO) && FOO
○: #if defined(FOO) && FOO
×: #ifdef defined(FOO) && FOO
○: #if defined(FOO) && FOO
804デフォルトの名無しさん
2022/02/06(日) 10:11:26.46ID:usxBX4wT805デフォルトの名無しさん
2022/02/06(日) 10:16:43.48ID:a0g451d/ 理由はたぶん、規格化以前に存在した実装の動作を規格違反とするのはマズいとか、
その動作に依存して #if FOO としてる既存ソースをエラーとするわけにはいかなかったとか、
そんなところだろうと思う。
マズい動作として検出したければ警告は出せるんだし。
その動作に依存して #if FOO としてる既存ソースをエラーとするわけにはいかなかったとか、
そんなところだろうと思う。
マズい動作として検出したければ警告は出せるんだし。
806デフォルトの名無しさん
2022/02/06(日) 11:57:03.48ID:qvD4QsX7 馬鹿がまだ騒いでるのかw
こういう変なコードとの対比w
$ g++ -x c++ - <<EOF
auto f = [](){return 2;};
#define f() 1
int main() {
auto i = f();
auto j = f;
return i + j();
}
EOF
$ ./a.out
$ echo $?
3
$
こういう変なコードとの対比w
$ g++ -x c++ - <<EOF
auto f = [](){return 2;};
#define f() 1
int main() {
auto i = f();
auto j = f;
return i + j();
}
EOF
$ ./a.out
$ echo $?
3
$
807はちみつ餃子 ◆8X2XSCHEME
2022/02/06(日) 12:12:45.00ID:u7K67HUJ 残った識別子を 0 に解釈する挙動は C89 からの仕様だから C89 の Rationale (根拠) を見たんだけど直接的な言及は見つからない。
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BxVCLS4f8Sg5NWZmM2NjZWEtYmExMS00Y2EzLWE3ZTMtNzFmYjYwYzBiOTIw&hl=en_US
ただ、既存のコードに差し障りがないようにということは明記してある (3.8.3) ので、
その時点でそういう挙動が支配的 (かつそれに依存するコードが多かった) のだろうとは察せられる。
規格ってのは統一を図るってのが第一の目的だけど無理な仕様でまとめちゃうと誰もその規格に従わないだけなんで、
現実にそれでやっているってのも (たとえ不格好でも) 十分な理由になるんだよ。
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BxVCLS4f8Sg5NWZmM2NjZWEtYmExMS00Y2EzLWE3ZTMtNzFmYjYwYzBiOTIw&hl=en_US
ただ、既存のコードに差し障りがないようにということは明記してある (3.8.3) ので、
その時点でそういう挙動が支配的 (かつそれに依存するコードが多かった) のだろうとは察せられる。
規格ってのは統一を図るってのが第一の目的だけど無理な仕様でまとめちゃうと誰もその規格に従わないだけなんで、
現実にそれでやっているってのも (たとえ不格好でも) 十分な理由になるんだよ。
808デフォルトの名無しさん
2022/02/06(日) 12:26:28.98ID:qvD4QsX7 そう書かれるとC89っぽく書かないといかんのか?w
変更部分のみw
$ gcc -x c -std=c89 - <<EOF
int f(void){return 2;}
#define f() 1
int main(void) {
int i;
int (*j)();
i = f();
j = &f;
return i + (*j)();
}
EOF
変更部分のみw
$ gcc -x c -std=c89 - <<EOF
int f(void){return 2;}
#define f() 1
int main(void) {
int i;
int (*j)();
i = f();
j = &f;
return i + (*j)();
}
EOF
809デフォルトの名無しさん
2022/02/06(日) 12:53:10.29ID:FF40fIFl CとC++の規格は既存コードへの忖度の塊で出来てるからな
万人の敵だったgets()を削除するのにどんだけ苦労してるのやら
万人の敵だったgets()を削除するのにどんだけ苦労してるのやら
810デフォルトの名無しさん
2022/02/06(日) 13:16:26.39ID:vWDceL4H811デフォルトの名無しさん
2022/02/06(日) 13:22:45.35ID:vWDceL4H >>807
C++規格委員会は無罪なのかもしれんがじゃあなんでC89以前からそうで
そういう挙動が支配的になってしまう事態になってしまったのか、と考えると
やっぱプリプロセッサの最初の設計者がサボって
プリプロセッサ式の途中でのFOOの定義/未定義判定を
define(FOO)を導入する代わりに仕様の方を弄って簡単ハックしてしまったから
のでは……
C++規格委員会は無罪なのかもしれんがじゃあなんでC89以前からそうで
そういう挙動が支配的になってしまう事態になってしまったのか、と考えると
やっぱプリプロセッサの最初の設計者がサボって
プリプロセッサ式の途中でのFOOの定義/未定義判定を
define(FOO)を導入する代わりに仕様の方を弄って簡単ハックしてしまったから
のでは……
812デフォルトの名無しさん
2022/02/06(日) 13:33:49.71ID:qvD4QsX7 コードを示しても馬鹿には伝わらない悲しみw
813デフォルトの名無しさん
2022/02/06(日) 13:37:12.22ID:vWDceL4H >>812
天才にもわかるようにkwsk
天才にもわかるようにkwsk
814デフォルトの名無しさん
2022/02/06(日) 13:39:17.55ID:qvD4QsX7 天才は自力でなんとか出来るし、他人を信用しないことも多いから、基本的に質問とかする機会がない
アイデアレベルの話のみ
アイデアレベルの話のみ
815デフォルトの名無しさん
2022/02/06(日) 14:11:31.07ID:Yc7Iwiyd (σ゚ω゚)σゲッツ
stdioのバッファ使うヤツ殆ど失敗作
stdioのバッファ使うヤツ殆ど失敗作
816デフォルトの名無しさん
2022/02/06(日) 14:22:31.03ID:yFNvdNoT #define マクロは単純置換のやつと関数形式のやつがある
#define A(a,b)
A();A(1);A(1,2,3);A(1,);A(,2);A;
結構めちゃくちゃなことやってもプリプロセスはエラー吐かない
引数足りないとか関数形式マクロの括弧がないのは意図しない使い方だろうからエラーにしてもらいたい気持ちはわかるが
というか<<802で言及されてるけど#if UNDEFINEDも非推奨にしてほしいわ
#define DEBUG
#define DEBUG 1
#define DEBUG 0
//#define DEBUG (undefined)
これらの全部のケースに対応できてねーし
#if DEBUG+0 とか書けとでも?
#define A(a,b)
A();A(1);A(1,2,3);A(1,);A(,2);A;
結構めちゃくちゃなことやってもプリプロセスはエラー吐かない
引数足りないとか関数形式マクロの括弧がないのは意図しない使い方だろうからエラーにしてもらいたい気持ちはわかるが
というか<<802で言及されてるけど#if UNDEFINEDも非推奨にしてほしいわ
#define DEBUG
#define DEBUG 1
#define DEBUG 0
//#define DEBUG (undefined)
これらの全部のケースに対応できてねーし
#if DEBUG+0 とか書けとでも?
817デフォルトの名無しさん
2022/02/06(日) 15:06:24.27ID:qvD4QsX7 俺のコードのg++やgccをcppに変えればプリプロセスの結果が出るよw オプション引数に-Eを付けても可w
別に不思議でも何でもない結果が表示されるw
$ cpp -x c++ - <<EOF
#define A(a,b) expanded
A();
A(1);
A(1,2,3);
A(1,);
A(,2);
A;
EOF
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
<stdin>:2:3: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:3:4: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:4:8: error: macro "A" passed 3 arguments, but takes just 2
<stdin>:1: note: macro "A" defined here
A;
expanded;
expanded;
A;
$
別に不思議でも何でもない結果が表示されるw
$ cpp -x c++ - <<EOF
#define A(a,b) expanded
A();
A(1);
A(1,2,3);
A(1,);
A(,2);
A;
EOF
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
<stdin>:2:3: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:3:4: error: macro "A" requires 2 arguments, but only 1 given
<stdin>:1: note: macro "A" defined here
A;
<stdin>:4:8: error: macro "A" passed 3 arguments, but takes just 2
<stdin>:1: note: macro "A" defined here
A;
expanded;
expanded;
A;
$
818デフォルトの名無しさん
2022/02/06(日) 16:46:37.28ID:XnD7OQcd インクルードガード書くときも単に
#define FOO_HPP
とするのと
#define FOO_HPP 1
と1にするのがあるがどちらが良いとかあるんだろうか
後者の方がconstexpr if文などのC++の言語機能と組み合わせて使えるというメリットがありそうだが
#define FOO_HPP
とするのと
#define FOO_HPP 1
と1にするのがあるがどちらが良いとかあるんだろうか
後者の方がconstexpr if文などのC++の言語機能と組み合わせて使えるというメリットがありそうだが
819デフォルトの名無しさん
2022/02/06(日) 16:54:43.06ID:W01LuusE 今から新規に書くなら #pragma once 一択
820はちみつ餃子 ◆8X2XSCHEME
2022/02/06(日) 17:09:14.27ID:u7K67HUJ >>818
私自身は前者にしてる。
インクルードしたことを示すためのフラグとしてのマクロが必要なら
(そういう事例に遭遇したことはないが) ガード用とは別にマクロ定義すると思う。
ガードのために定義したものをガード以外の目的で使うというのがちょっと汚く感じるから。
だけど分けちゃうと管理が二重になるのが嫌だと思う人もいるだろうし、
思想によるんじゃないの。
私は規格厨なので #pragma once は使わない。
まあ gcc と clang と msvc で使えるから事実上は問題にならないけど。
私自身は前者にしてる。
インクルードしたことを示すためのフラグとしてのマクロが必要なら
(そういう事例に遭遇したことはないが) ガード用とは別にマクロ定義すると思う。
ガードのために定義したものをガード以外の目的で使うというのがちょっと汚く感じるから。
だけど分けちゃうと管理が二重になるのが嫌だと思う人もいるだろうし、
思想によるんじゃないの。
私は規格厨なので #pragma once は使わない。
まあ gcc と clang と msvc で使えるから事実上は問題にならないけど。
821デフォルトの名無しさん
2022/02/06(日) 17:25:15.43ID:XnD7OQcd822はちみつ餃子 ◆8X2XSCHEME
2022/02/06(日) 17:46:04.51ID:u7K67HUJ >>821
NDEBUG は「デバッグモードとそうでないモードを切り替える」というのがその用途なので
それに沿うと思ったら分けずに NDEBUG を使うことはあるよ。
でも「NDEBUG の用途は assert の有効・無効の切り替えなので他に使うべきでない」と認識している人がいてもおかしくない。
規格に書いてあるのはこの場合はこうだという規則だけなので
抽象的な部分での意味の捉え方は人によってかなり幅がある。
そのあたりは文脈を察して常識的判断でやっていくしかないし、
チームでやってるなら話し合うしかしょうがない。
このへんはそんなにスッパリと判断基準を設けられるようなもんではないと思う。
NDEBUG は「デバッグモードとそうでないモードを切り替える」というのがその用途なので
それに沿うと思ったら分けずに NDEBUG を使うことはあるよ。
でも「NDEBUG の用途は assert の有効・無効の切り替えなので他に使うべきでない」と認識している人がいてもおかしくない。
規格に書いてあるのはこの場合はこうだという規則だけなので
抽象的な部分での意味の捉え方は人によってかなり幅がある。
そのあたりは文脈を察して常識的判断でやっていくしかないし、
チームでやってるなら話し合うしかしょうがない。
このへんはそんなにスッパリと判断基準を設けられるようなもんではないと思う。
823デフォルトの名無しさん
2022/02/06(日) 19:09:51.99ID:qvD4QsX7 MS発祥のモノが嫌われてるだけとも思うw
824デフォルトの名無しさん
2022/02/06(日) 19:46:48.16ID:XnD7OQcd825はちみつ餃子 ◆8X2XSCHEME
2022/02/06(日) 20:08:36.06ID:u7K67HUJ >>824
基本的には前者。
フラグとしてのマクロで分岐するときは #if よりも #ifdef (または defined) を使うようにしてる。
マクロは型を付けられないからそうすることで ON/OFF のどちらかであって内容に意味はない
ことを明示してる感じを出したいと思ってる。
基本的には前者。
フラグとしてのマクロで分岐するときは #if よりも #ifdef (または defined) を使うようにしてる。
マクロは型を付けられないからそうすることで ON/OFF のどちらかであって内容に意味はない
ことを明示してる感じを出したいと思ってる。
826デフォルトの名無しさん
2022/02/06(日) 20:55:43.12ID:XnD7OQcd827デフォルトの名無しさん
2022/02/07(月) 06:01:51.26ID:a2THiWt1 #pragma onceを標準に採用すればええのに
これだけ需要あるのに長年ずっと放置状態
何がそんなに問題なんだろう
これだけ需要あるのに長年ずっと放置状態
何がそんなに問題なんだろう
828はちみつ餃子 ◆8X2XSCHEME
2022/02/07(月) 09:54:39.71ID:T4nofIq4 現行仕様での理屈の立て方としては #include の効果でコードに一体化してから内容の解釈が始まるので
インクルードに干渉する余地がない。
現実にやってるんだから出来るのは間違いないんだけど理屈を根本から変えることになるし、
モジュールが上手くいけばどうでもよくなることに手間をかけたくないんじゃないかな。
インクルードに干渉する余地がない。
現実にやってるんだから出来るのは間違いないんだけど理屈を根本から変えることになるし、
モジュールが上手くいけばどうでもよくなることに手間をかけたくないんじゃないかな。
829デフォルトの名無しさん
2022/02/07(月) 11:19:39.20ID:3u4X3WRg シンボリックリンクで別のパスになってたりとか、同じ内容の別ファイルとか、ファイル名違う中身同じファイルとか、日付だけ違う別ディレクトリの同じ内容のファイルとか
そんなの考えたくないよなーw
そんなの考えたくないよなーw
830はちみつ餃子 ◆8X2XSCHEME
2022/02/07(月) 11:53:54.22ID:T4nofIq4 名前と実体をどう対応付けるかは今でも処理系定義なのでそこらへんはあまり問題にならないと思う。
831デフォルトの名無しさん
2022/02/07(月) 11:56:53.41ID:XrnUHtPA そこで#pragma onceはヘッダファイルそのものをインクルード済とみなすのではなくて
定義されている内容を定義済みと記憶するのが妥当な動作
なんだけど以下のような場合に困るという、
"a.h"
struct Foo {
"b.h"
int m_x;
double m_y;
};
"c.cpp"
#include "a.h"
#include "b.h"
やっぱモジュールにしたら同じような実装で完全な解決になるのだから待った方が、
定義されている内容を定義済みと記憶するのが妥当な動作
なんだけど以下のような場合に困るという、
"a.h"
struct Foo {
"b.h"
int m_x;
double m_y;
};
"c.cpp"
#include "a.h"
#include "b.h"
やっぱモジュールにしたら同じような実装で完全な解決になるのだから待った方が、
832デフォルトの名無しさん
2022/02/07(月) 12:22:03.46ID:XrnUHtPA 現行の
#ifdef _FOO_H_
#define _FOO_H_
....
#endif
はヘッダファイルをインクルード済みか否かではなく
マクロ_FOO_H_が定義済みか否かを問題にしているのである意味モジュールに近い
#pragma onceは現行のマイクロソフトのやつはヘッダファイルをインクルード済みか否かを問題にしているので
何をもって同一のヘッダファイルとみなすのかという解釈の揺らぎの影響を受けてしまうまインクルードの挙動が、
#ifdef _FOO_H_
#define _FOO_H_
....
#endif
はヘッダファイルをインクルード済みか否かではなく
マクロ_FOO_H_が定義済みか否かを問題にしているのである意味モジュールに近い
#pragma onceは現行のマイクロソフトのやつはヘッダファイルをインクルード済みか否かを問題にしているので
何をもって同一のヘッダファイルとみなすのかという解釈の揺らぎの影響を受けてしまうまインクルードの挙動が、
833デフォルトの名無しさん
2022/02/07(月) 12:25:19.77ID:3u4X3WRg >>830
だからどう転ぼうと中身で決められる昔ながらの方法の方が結果が明確ということw
ちなみにgccは
シンボリックリンク→ガード
同じ内容・日付・名前、別ディレクトリの別ファイル→ガード
同じ内容・名前、別日付、ディレクトリの別ファイル→インクルード
同じ内容・日付、別名前、ディレクトリの別ファイル→インクルード
みたい
だからどう転ぼうと中身で決められる昔ながらの方法の方が結果が明確ということw
ちなみにgccは
シンボリックリンク→ガード
同じ内容・日付・名前、別ディレクトリの別ファイル→ガード
同じ内容・名前、別日付、ディレクトリの別ファイル→インクルード
同じ内容・日付、別名前、ディレクトリの別ファイル→インクルード
みたい
834デフォルトの名無しさん
2022/02/07(月) 12:42:43.58ID:OoGLA1C8 MSの手抜き仕様まで合わせる必要なし
835デフォルトの名無しさん
2022/02/07(月) 12:56:32.61ID:3qCWHTEM でもCに代わってC++が広まったのはMSのおかげじゃん
836デフォルトの名無しさん
2022/02/07(月) 13:10:46.99ID:a2THiWt1 ビット数多めのハッシュにしとけば
例えば衝突確率340澗分の1とかにできるよな
例えば衝突確率340澗分の1とかにできるよな
837デフォルトの名無しさん
2022/02/09(水) 12:59:20.15ID:ioLTStxt 64bit osでポインタ型を4byteにするにはどうすればいいんですか?
8byteだとちょっと大きすぎる気がします
8byteだとちょっと大きすぎる気がします
838デフォルトの名無しさん
2022/02/09(水) 13:03:37.90ID:IwR5waiE なぜ大きすぎると思ったのかが分からないが、64bitのアドレス空間を表すのに8 byteは必要だよ
839デフォルトの名無しさん
2022/02/09(水) 13:08:06.15ID:PzVUb2uc >>837
貧乏くさすぎ
貧乏くさすぎ
840デフォルトの名無しさん
2022/02/09(水) 13:19:23.53ID:eAgudC7+ 64bit WindowsOSなら32bitアプリにすればok
841デフォルトの名無しさん
2022/02/09(水) 13:40:55.45ID:ioLTStxt 例えば64bitの場合アドレスの上位4byteを一意に決めといて下位4byteを4byteの変数に格納しておくってやり方なんてはどうですか?
それで復元時には
(上位4byte << 32) & 下位4byteっていうふうに変換するってふうになると思うんですが
まず最初に上位4byteが一致した連続したメモリ領域から決まってメモリを確保するなんてことはできるのでしょうか?
それで復元時には
(上位4byte << 32) & 下位4byteっていうふうに変換するってふうになると思うんですが
まず最初に上位4byteが一致した連続したメモリ領域から決まってメモリを確保するなんてことはできるのでしょうか?
842デフォルトの名無しさん
2022/02/09(水) 13:52:00.55ID:USCqmiY8 必要なメモリをvector<X>で確保しておいて32bit以下のindex値でアクセスすることにすれば?
ポインタのサイズが大きすぎるなんて理由でやる人はいないと思うけど
ポインタのサイズが大きすぎるなんて理由でやる人はいないと思うけど
843デフォルトの名無しさん
2022/02/09(水) 13:52:47.57ID:E/6u1YW1 long long ago... タイニー、スモール、コンパクト、ミディアム、ラージ、ヒュージつーのがあってだな
844デフォルトの名無しさん
2022/02/09(水) 14:26:32.14ID:ioLTStxt845デフォルトの名無しさん
2022/02/09(水) 14:34:15.15ID:PzVUb2uc 関数ポインタかなんかが8バイトに収まってなくて混乱したことがあったっけ
846デフォルトの名無しさん
2022/02/09(水) 14:37:12.22ID:Jq7h8mT9 昔は16bitポインタと32bitポインタをLPとPで使い分けてたって戦争で死んだおじいちゃんに聞いた
847デフォルトの名無しさん
2022/02/09(水) 17:17:57.87ID:SS+/CtsS segment:offset時代か・・・
848デフォルトの名無しさん
2022/02/09(水) 18:17:45.02ID:t2vkJvVR アセンブラの相対ショートジャンプは8ビット
849デフォルトの名無しさん
2022/02/09(水) 22:34:51.11ID:9agulkW+ ウィンドーズならINT_PTR使っとけばおkオール無問題
C++の標準規格でどうなっているのかわ知らん
C++の標準規格でどうなっているのかわ知らん
850はちみつ餃子 ◆8X2XSCHEME
2022/02/09(水) 23:19:57.51ID:9Cj+df9g 規格上は std::intptr_t というものがある。
ただし関数ポインタやメンバ関数ポインタを格納できるとは限らない。
また、省略可能 (optional) であると明記されているので無くても規格準拠たりうる。
関数ポインタ同士 (メンバ関数ポインタは含まない) はお互いに変換可能であり
元の型にキャストしたら元の値と等しくなることは保証されるので
任意の型の関数ポインタを格納したいのであれば void* や intptr_t を使うよりは
適当な型の関数ポインタに入れるほうが規格に沿う。
メンバ関数ポインタは型通りに扱う以外はほとんど何の保証もないのだけれど
無理に変換して扱いたい場合も特に思いつかないのでどうでもいい。
ただし関数ポインタやメンバ関数ポインタを格納できるとは限らない。
また、省略可能 (optional) であると明記されているので無くても規格準拠たりうる。
関数ポインタ同士 (メンバ関数ポインタは含まない) はお互いに変換可能であり
元の型にキャストしたら元の値と等しくなることは保証されるので
任意の型の関数ポインタを格納したいのであれば void* や intptr_t を使うよりは
適当な型の関数ポインタに入れるほうが規格に沿う。
メンバ関数ポインタは型通りに扱う以外はほとんど何の保証もないのだけれど
無理に変換して扱いたい場合も特に思いつかないのでどうでもいい。
851デフォルトの名無しさん
2022/02/10(木) 02:00:13.27ID:vaE+JZMI >>843
far/near を直接指定すれはすむ話、メモリモデルなんてどうでもいい
far/near を直接指定すれはすむ話、メモリモデルなんてどうでもいい
852デフォルトの名無しさん
2022/02/10(木) 19:32:52.48ID:OsDlZl05 effective C++って現行のC++と比べてどのあたりが古いんですか?
代表的なところとかだけでも教えてくれると嬉しいです
代表的なところとかだけでも教えてくれると嬉しいです
853デフォルトの名無しさん
2022/02/10(木) 19:38:59.22ID:NUzD8R/O 全て
854デフォルトの名無しさん
2022/02/10(木) 20:00:39.81ID:qtJUe0L+ 出版1998年やんけ
こんなもん使うぐらいならC言語やった方がマシなレベル
こんなもん使うぐらいならC言語やった方がマシなレベル
855デフォルトの名無しさん
2022/02/10(木) 20:11:39.77ID:OsDlZl05 >>854
一応第3版は原書が2005年に書かれています…
一応第3版は原書が2005年に書かれています…
856デフォルトの名無しさん
2022/02/10(木) 20:20:25.92ID:ZkLGowhi 続編のeffective modern c++も古いけど、
こっちは隕石落下後の本だから読んでおいたほうがいいよ
こっちは隕石落下後の本だから読んでおいたほうがいいよ
857デフォルトの名無しさん
2022/02/10(木) 21:18:10.31ID:OsDlZl05 隕石落下後ってなんすか?
あとC++の勉強するならこの本読め、みたいなのって他にもありますか?
あとC++の勉強するならこの本読め、みたいなのって他にもありますか?
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【中国外務省】日中関係悪化は高市氏に責任と名指しで非難… ★5 [BFU★]
- 【インバウンド】中国からの“渡航自粛”…ツアー1000人分の直前キャンセル「キャンセル料は免除してくれ」 ことしいっぱいキャンセルに [1ゲットロボ★]
- XやChatGPTで広範囲の通信障害 投稿や閲覧できず [蚤の市★]
- 「国民の憤りを引き起こした」中国側“高市首相発言の撤回改めて要求” [どどん★]
- 【サッカー】日本代表、ボリビアに3発快勝 森保監督通算100試合目を飾る…鎌田、町野、中村がゴール [久太郎★]
- 【ローソン】ロゴの「L」で誤解生んだコーヒーカップ、デザイン変更へ 在庫使い切る3か月後にリニューアル [ぐれ★]
- 【悲報】SANA、発言撤回拒否 [769931615]
- 岡田克也「軽々しく存立危機事態とか言うべきじゃない」高市早苗「台湾で武力攻撃が発生したらどう考えても日本の存立危機事態」 [931948549]
- 米シンクタンク「アメリカは台湾問題で"あいまい戦略"を取っている。高市早苗はこの方針から逸脱している」 [603416639]
- ジャーナリストがテレビで解説「台湾問題は高市総理から言ったのではなく、立憲民主が日本の対応可能能力を暴こうとしたから」 [359572271]
- 俺性格悪いなって思った瞬間あげてけ
- 船井「ククク…♥残念やけどカイジさんはこれで別室行きや…♥」黒服「来いっ…♥」カイジ「やめろ!やめてくれっ…!」
