!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512
↑同じ内容を3行貼り付けること
次スレは>>980が立てること
無理なら細かく安価指定
※前スレ
C++相談室 part163
https://mevius.5ch.net/test/read.cgi/tech/1672409791/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
探検
C++相談室 part164
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 33da-QP0H)
2023/05/09(火) 11:50:52.06ID:EYc2I7oW0240デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/18(日) 21:48:16.43ID:VwYqKwPk0 >>239
レス有難うございます
まず訂正
-accumulate
+std::accumulate
全部は貼れないですけど大事そうなところ
In file included from /usr/include/c++/12/numeric:62,
from test1.cpp:18:
/usr/include/c++/12/bits/stl_numeric.h: In instantiation of ‘constexpr _Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = _Deque_iterator<array<double, 3>, array<double, 3>&, array<double, 3>*>; _Tp = array<double, 3>]’:
test1.cpp:22:14: required from here
/usr/include/c++/12/bits/stl_numeric.h:141:46: error: no match for ‘operator+’ (operand types are ‘std::remove_reference<std::array<double, 3>&>::type’ {aka ‘std::array<double, 3>’} and ‘std::array<double, 3>’)
141 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
レス有難うございます
まず訂正
-accumulate
+std::accumulate
全部は貼れないですけど大事そうなところ
In file included from /usr/include/c++/12/numeric:62,
from test1.cpp:18:
/usr/include/c++/12/bits/stl_numeric.h: In instantiation of ‘constexpr _Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = _Deque_iterator<array<double, 3>, array<double, 3>&, array<double, 3>*>; _Tp = array<double, 3>]’:
test1.cpp:22:14: required from here
/usr/include/c++/12/bits/stl_numeric.h:141:46: error: no match for ‘operator+’ (operand types are ‘std::remove_reference<std::array<double, 3>&>::type’ {aka ‘std::array<double, 3>’} and ‘std::array<double, 3>’)
141 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
241デフォルトの名無しさん (ワッチョイ 9e81-L1I+)
2023/06/18(日) 23:15:51.41ID:w3/xAOT+0 ADLでoperator+が見つからないからかな?
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
242デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/18(日) 23:20:13.62ID:VwYqKwPk0243デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
2023/06/18(日) 23:24:52.33ID:bX3uBTIT0 std::accumulateが14行目で定義したoperator+を見つけれてないのが原因っぽい。
std::accumulateの第4引数に
[](const Vector& v1, const Vector& v2){ return v1+v2;}
を追加してやるとコンパイルは通る。
14行目のoperator+をstd名前空間に入れてやれば動くにゃ動くけど色々マズいので(調査する分にはいいけど)最終的な解答にはならないかな
std::accumulateの第4引数に
[](const Vector& v1, const Vector& v2){ return v1+v2;}
を追加してやるとコンパイルは通る。
14行目のoperator+をstd名前空間に入れてやれば動くにゃ動くけど色々マズいので(調査する分にはいいけど)最終的な解答にはならないかな
244デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
2023/06/18(日) 23:29:04.68ID:bX3uBTIT0 >>242
たぶんC++コンパイラはoperator+の候補を検索するときに
Vector( = std::array<double, 3>)と同じ名前空間にあるものしか検索しない
Vectorのクラス定義そのものがグローバル名前空間にあるなら14行目のoperator+を見つけられるけど、
今はVectorの正体はstd::array<...>なのでstd名前空間しか検索しないんだと思う
たぶんC++コンパイラはoperator+の候補を検索するときに
Vector( = std::array<double, 3>)と同じ名前空間にあるものしか検索しない
Vectorのクラス定義そのものがグローバル名前空間にあるなら14行目のoperator+を見つけられるけど、
今はVectorの正体はstd::array<...>なのでstd名前空間しか検索しないんだと思う
245デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/18(日) 23:39:19.50ID:VwYqKwPk0246デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/18(日) 23:48:03.44ID:EGGkT3O00 独自のメンバ変数を持たないのなら継承してしまうのも手ではある(ただしコンストラクタやarrayを受け取るキャスト用コンストラクタとか書く必要が出ると思うけど)
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
247デフォルトの名無しさん (ワッチョイ b110-lSMs)
2023/06/19(月) 00:42:02.49ID:2lgIrH6A0 >>245
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
248デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/19(月) 00:52:39.28ID:Q4g6N6uX0 >>247
std::accumlateが定義されているnumericをincludeする前に
以下のようにグローバルスコープにプロトタイプを置いても
同じようにoperator+が見えてないとエラーが出ます
using Vector = std::array <double, 3>;
Vector operator + (const Vector &lhs, const Vector &rhs);
#include <numeric>
std::accumlateが定義されているnumericをincludeする前に
以下のようにグローバルスコープにプロトタイプを置いても
同じようにoperator+が見えてないとエラーが出ます
using Vector = std::array <double, 3>;
Vector operator + (const Vector &lhs, const Vector &rhs);
#include <numeric>
249デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/19(月) 03:40:46.00ID:RYn53SnN0 accumlateは関数テンプレートだから実体化される時点でoperator+が見えてりゃOKのはず
言われてる通りADLで対象外なのが問題
言われてる通りADLで対象外なのが問題
250デフォルトの名無しさん (ワッチョイ 256b-trtU)
2023/06/19(月) 05:38:23.58ID:JAsvvATP0 >>237
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
251デフォルトの名無しさん (ワッチョイ f59c-Axrn)
2023/06/19(月) 08:48:03.43ID:KLBRX38t0252デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/19(月) 09:20:16.57ID:Q4g6N6uX0 >>249
有難うございます
グローバルスコープに定義した関数が見えないのは
どうしてなんでしょうかね?
それでは全然グローバルじゃないような気がするのですが
規格を決めるときに何か意図があったのでしょうかね?
有難うございます
グローバルスコープに定義した関数が見えないのは
どうしてなんでしょうかね?
それでは全然グローバルじゃないような気がするのですが
規格を決めるときに何か意図があったのでしょうかね?
253デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/19(月) 10:39:37.41ID:RYn53SnN0 そもそもが名前空間内(よその演算子と混ざらないように)にある演算子オーバーロードを、外部からでも引数が合えば使えるように(std::operator+(a, b)とか書かないでいいように)するためのルールらしいから
外部の演算子見に行くのは目的に合わんのじゃね
std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、あまりよろしくないやり方しようとしてると考えた方がいい
(だから>>246のように書いた、継承したら一応arrayではなくちゃんとVectorクラスに対する演算子だから通る)
外部の演算子見に行くのは目的に合わんのじゃね
std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、あまりよろしくないやり方しようとしてると考えた方がいい
(だから>>246のように書いた、継承したら一応arrayではなくちゃんとVectorクラスに対する演算子だから通る)
254デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/19(月) 11:53:54.08ID:Q4g6N6uX0255デフォルトの名無しさん (ワッチョイ 5efb-+wmN)
2023/06/19(月) 12:20:34.90ID:4PINPeBN0 つまりvector<int>を使いなさいということ
256デフォルトの名無しさん (ワッチョイ 7d9b-trtU)
2023/06/19(月) 12:21:25.69ID:wGtx/iKL0 >>251
安価ミス
安価ミス
257デフォルトの名無しさん (アウアウウー Sacd-9XmN)
2023/06/20(火) 00:04:57.81ID:YSi65ASja 実引数依存の名前探索、Argument-Dependent Lookup (ADL)は、
Koenig lookup とも言う
「Cプログラミングの落とし穴」の著者、
Koenigが、C++ に入れる事を推奨した
ADLを知っているなら、かなりのプロと言える
Koenig lookup とも言う
「Cプログラミングの落とし穴」の著者、
Koenigが、C++ に入れる事を推奨した
ADLを知っているなら、かなりのプロと言える
258デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 00:18:46.72ID:vGfe0Eju0 勉強になります
259デフォルトの名無しさん (アウアウウー Sacd-9XmN)
2023/06/20(火) 02:12:24.83ID:1vctBLGTa 演算子のオーバーロードなら、フレンド関数とか?
非メンバの演算子オーバーロード | Programming Place Plus C++編【言語解説】 第35章
https://programming-place.net/ppp/contents/cpp/language/035.html
非メンバの演算子オーバーロード | Programming Place Plus C++編【言語解説】 第35章
https://programming-place.net/ppp/contents/cpp/language/035.html
260はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 10:05:39.77ID:IIzrqfbq0 状況を簡略化するとこう。
namespace ns {
struct foo {};
template <class T>
void bar(const T&) {
T() + T();
} };
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
int main() { bar(ns::foo()); }
ADL は「通常の探索に加えて」関連する名前空間も探索対象にするルールなのでグローバル名前空間も探索対象になるが、通常の探索では後ろで宣言 (定義) されているものは見つけることができない。 この場合はエラーとして検出されるけど、可視な宣言と実際の定義の集合に食い違いは未定義という解釈でいいと思う。 (ちょっと自信はない……。)
だから順序を変えれば通る。
namespace ns {
struct foo{};
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo()); }
当然ながら std の (というかそれに限らず既存のライブラリの) 宣言の順序をどうこうするわけにもいかないので無理にカスタムしようとするのは筋が悪いということになる。
namespace ns {
struct foo {};
template <class T>
void bar(const T&) {
T() + T();
} };
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
int main() { bar(ns::foo()); }
ADL は「通常の探索に加えて」関連する名前空間も探索対象にするルールなのでグローバル名前空間も探索対象になるが、通常の探索では後ろで宣言 (定義) されているものは見つけることができない。 この場合はエラーとして検出されるけど、可視な宣言と実際の定義の集合に食い違いは未定義という解釈でいいと思う。 (ちょっと自信はない……。)
だから順序を変えれば通る。
namespace ns {
struct foo{};
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo()); }
当然ながら std の (というかそれに限らず既存のライブラリの) 宣言の順序をどうこうするわけにもいかないので無理にカスタムしようとするのは筋が悪いということになる。
261デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 10:53:08.18ID:vGfe0Eju0 >>260
>だから順序を変えれば通る。
最近手元のg++を更新しまして10.2.1 -> 12.2.0になったんですが
前者のケースが通らなくなりまして疑問に思っていたところでした
10.2.1は寛容で両方とも通るけどC++的には後者のみ通るのが正しい?
>だから順序を変えれば通る。
最近手元のg++を更新しまして10.2.1 -> 12.2.0になったんですが
前者のケースが通らなくなりまして疑問に思っていたところでした
10.2.1は寛容で両方とも通るけどC++的には後者のみ通るのが正しい?
262はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 11:41:30.21ID:IIzrqfbq0 >>261
前者はたぶん未定義かつ診断不要な状況なのでエラーを検出せずに通すのも正しい挙動で
プログラマがそういう状況を作ってしまうのが仕様に反する (というか結果が保証されない) という解釈になると思う。
前者はたぶん未定義かつ診断不要な状況なのでエラーを検出せずに通すのも正しい挙動で
プログラマがそういう状況を作ってしまうのが仕様に反する (というか結果が保証されない) という解釈になると思う。
263デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 13:36:04.44ID:vGfe0Eju0 なるほどー
有難うございます
有難うございます
264デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 21:39:35.82ID:Pk8V/jejH template<typename Callback>
void func(Callback cb)
{
//cb(1); // A
//cb(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
AとBをコンパイル時に呼び分けたいんですけど
どのように記述すればよいか教えていただけませんか?
void func(Callback cb)
{
//cb(1); // A
//cb(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
AとBをコンパイル時に呼び分けたいんですけど
どのように記述すればよいか教えていただけませんか?
265デフォルトの名無しさん (ワッチョイ 515f-9XmN)
2023/06/20(火) 22:18:37.18ID:Cuq1USIJ0 is_invocableでおk
266はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 22:21:49.81ID:IIzrqfbq0 >>264
渡されたコールバック関数の引数の数によって区別するってこと?
素朴な方法だとオーバーロードするのが手っ取り早いと思う。
void func(void (*cb)(int)) {
cb(1);
}
void func(void (*cb)(int, int)) {
cb(1, 2);
}
void f1(int) {}
void f2(int, int) {}
int main() {
func(f1);
func(f2);
}
渡されたコールバック関数の引数の数によって区別するってこと?
素朴な方法だとオーバーロードするのが手っ取り早いと思う。
void func(void (*cb)(int)) {
cb(1);
}
void func(void (*cb)(int, int)) {
cb(1, 2);
}
void f1(int) {}
void f2(int, int) {}
int main() {
func(f1);
func(f2);
}
267デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:27:55.14ID:vGfe0Eju0 >>264
template<typename Callback> void func(Callback cb);
template <> void func(void (*cb) (int))
{
(*cb)(1); // A
}
template <> void func(void (*cb) (int, int))
{
(*cb)(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
template<typename Callback> void func(Callback cb);
template <> void func(void (*cb) (int))
{
(*cb)(1); // A
}
template <> void func(void (*cb) (int, int))
{
(*cb)(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
268デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:29:12.98ID:vGfe0Eju0 templateが意味ないね
269デフォルトの名無しさん (ワッチョイ 127f-L1I+)
2023/06/20(火) 22:39:00.27ID:ui/rWsWf0 265が言うようにis_invocable使うとこんな感じ?
template<typename Callback>
void func(Callback cb)
{
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
}
template<typename Callback>
void func(Callback cb)
{
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
}
270デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:41:37.75ID:vGfe0Eju0 >>269
これって関係ないif節はコンパイル時に消えるの?
これって関係ないif節はコンパイル時に消えるの?
272デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 22:44:14.18ID:Pk8V/jejH273デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:47:27.45ID:vGfe0Eju0274デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 22:48:18.64ID:Pk8V/jejH >>269
まさにこれをやりたかったです。
template<typename Callback>
void func(Callback cb)
{
// こことか
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
// ここをどうしようか悩んでいました
}
まさにこれをやりたかったです。
template<typename Callback>
void func(Callback cb)
{
// こことか
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
// ここをどうしようか悩んでいました
}
275はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 22:59:00.24ID:IIzrqfbq0276デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 23:14:31.48ID:Pk8V/jejH277デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/20(火) 23:42:05.71ID:zCL4VLm70 >>273
ザッツcostexprマジック
ザッツcostexprマジック
278デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/20(火) 23:43:57.61ID:zCL4VLm70 n抜けてたwコストがかかる演算なのは確かだけどw
constexprマジック!マジック!
constexprマジック!マジック!
279デフォルトの名無しさん (ワッチョイ 32fb-dYQK)
2023/06/21(水) 00:07:10.76ID:2lh42auf0 C++11のSFIANE地獄へようこそ
https://wandbox.org/permlink/2sfUVeEBrErqvI2R
template関数の実体化が1つだけ成功して、
他が失敗するように仕掛ければ呼び分けは可能。
ただ見ての通り相当面倒なことを書かなきゃならない。
https://wandbox.org/permlink/2sfUVeEBrErqvI2R
template関数の実体化が1つだけ成功して、
他が失敗するように仕掛ければ呼び分けは可能。
ただ見ての通り相当面倒なことを書かなきゃならない。
280デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/21(水) 00:28:02.40ID:CWKUsltc0281はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 00:41:42.51ID:3HBFHOpK0282デフォルトの名無しさん (ワッチョイ 515f-9XmN)
2023/06/21(水) 00:42:09.27ID:LxMKpynY0 templateでやるのは質問者の与えた要件だな
宿題なんじゃね、しらんけど
宿題なんじゃね、しらんけど
283デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
2023/06/21(水) 00:52:13.25ID:2lh42auf0 C++14にはif constexprが存在しないから
template使ったオーバーロードしか手段がない
質問者がC++14環境でって言ってたからこんなクソ面倒くさいことやれば一応できるっていう例示
template使ったオーバーロードしか手段がない
質問者がC++14環境でって言ってたからこんなクソ面倒くさいことやれば一応できるっていう例示
284デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/21(水) 01:17:47.52ID:CWKUsltc0 >>281,283
ありがとう
>引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
>厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
こういうことね
ありがとう
>引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
>厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
こういうことね
285デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/21(水) 04:29:46.61ID:IDPPhD2V0 >>260
あー本来グローバルも対象になるのか、適当こいてスマソ
だが>>248で質問者が言ってるように、元のコードで順序を変えてもダメなのよ
何故か考えてはちみつのコードを以下のようにしたら同様に通らなかった
namespace ns {
template <class T = int>
struct foo{};
// added
struct hoge{};
int operator +(const hoge &x, const hoge &y) {return 1;}
};
ns::foo<> operator+(const ns::foo<>& x, const ns::foo<>& y) { return ns::foo<>(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo<>()); }
すでに名前空間内に同名の関数があった場合はダメっぽい
あー本来グローバルも対象になるのか、適当こいてスマソ
だが>>248で質問者が言ってるように、元のコードで順序を変えてもダメなのよ
何故か考えてはちみつのコードを以下のようにしたら同様に通らなかった
namespace ns {
template <class T = int>
struct foo{};
// added
struct hoge{};
int operator +(const hoge &x, const hoge &y) {return 1;}
};
ns::foo<> operator+(const ns::foo<>& x, const ns::foo<>& y) { return ns::foo<>(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo<>()); }
すでに名前空間内に同名の関数があった場合はダメっぽい
286デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/21(水) 09:44:10.00ID:IDPPhD2V0 あ、すまんfooがクラステンプレートになってるの直し忘れた(直しても同じだが)
287はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 10:22:19.76ID:3HBFHOpK0 >>285
名前探索 (name lookup) は狭い名前空間から探索していって
合致する名前があればそれより外側に同名の関数があっても
オーバーロード解決に参加しない。
わかりやすい例で言えばメンバ関数は非メンバより優先されるし、
メンバ関数内にひとつでも候補が見つかった時点で非メンバ関数は一切考慮に入らなくなる。
void foo(void) {}
struct bar {
void baz(void) {
// この foo は bar::foo のこと
// 名前が見つかった時点でそれより外の名前空間は見に行かないので
// 引数が合わなくても他の候補は試みられずエラーになる。
foo(1);
}
void foo(void) {}
};
名前探索 (name lookup) は狭い名前空間から探索していって
合致する名前があればそれより外側に同名の関数があっても
オーバーロード解決に参加しない。
わかりやすい例で言えばメンバ関数は非メンバより優先されるし、
メンバ関数内にひとつでも候補が見つかった時点で非メンバ関数は一切考慮に入らなくなる。
void foo(void) {}
struct bar {
void baz(void) {
// この foo は bar::foo のこと
// 名前が見つかった時点でそれより外の名前空間は見に行かないので
// 引数が合わなくても他の候補は試みられずエラーになる。
foo(1);
}
void foo(void) {}
};
288はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 10:34:08.97ID:3HBFHOpK0 例をちょっと間違えたのでやりなおし。
void foo(int) {}
struct bar {
void baz(void) {
foo(1);
}
void foo(void) {}
};
こうすると非メンバ関数の foo は候補にすらならないという話。
void foo(int) {}
struct bar {
void baz(void) {
foo(1);
}
void foo(void) {}
};
こうすると非メンバ関数の foo は候補にすらならないという話。
289デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/21(水) 11:00:59.24ID:CWKUsltc0 g++更新にともない
自前ライブラリのビルドでエラーが出るようになって
悩んでたところを解説してくれてる
マジで凄い人達だな
自前ライブラリのビルドでエラーが出るようになって
悩んでたところを解説してくれてる
マジで凄い人達だな
290デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/21(水) 11:31:26.94ID:IDPPhD2V0 >メンバ関数内にひとつでも候補が見つかった時点で非メンバ関数は一切考慮に入らなくなる。
thx。確かにこれ経験したことあるわ・・・ややこしいし名前変えて対処したけど
thx。確かにこれ経験したことあるわ・・・ややこしいし名前変えて対処したけど
291はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 12:13:25.08ID:3HBFHOpK0 >>285 の例は using を使う形でも解決できる。 (設計意図によってはそれが妥当かどうかわからんけど。)
namespace ns {
struct foo {};
struct hoge {};
int operator+(const hoge& x, const hoge& y) { return 1; }
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
using ::operator+; // グローバルな operator+ をオーバーロード候補として参加させる
T() + T();
}
};
int main() { bar(ns::foo()); }
テンプレートを見る機会がよくあるなら std::begin を using している事例は見たことがあると思う。
namespace ns {
struct foo {};
struct hoge {};
int operator+(const hoge& x, const hoge& y) { return 1; }
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
using ::operator+; // グローバルな operator+ をオーバーロード候補として参加させる
T() + T();
}
};
int main() { bar(ns::foo()); }
テンプレートを見る機会がよくあるなら std::begin を using している事例は見たことがあると思う。
292デフォルトの名無しさん (ワッチョイ ad10-fL0y)
2023/06/21(水) 12:20:53.22ID:s1sJDdcu0 C++って、こういう悪夢みたいなテクニックで溢れかえってるよなあ
RustやらPythonだのに人気が移るわけですよ
RustやらPythonだのに人気が移るわけですよ
293デフォルトの名無しさん (テテンテンテン MM96-Axrn)
2023/06/21(水) 12:23:49.28ID:xjKiS8Z6M 記法でいうならNimがいいよ。
294はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 16:00:35.62ID:3HBFHOpK0 カスタマイズされた関数が呼ばれるようにする綺麗な方法として customization point object という概念が近頃は導入されてる。
綺麗な方法というか汚い部分はライブラリに隠すってだけなんだけど。
真似してみてもいいかもね。
より綺麗な方法が導入されるのはいいんだけど、
過去の方法が消えてなくなるわけでもないし完全に置き換えられるわけでもないからなぁ。
個々には良くなっても全体としては余計に複雑になるだけってのもよくある話。
https://m.xkcd.com/927/
綺麗な方法というか汚い部分はライブラリに隠すってだけなんだけど。
真似してみてもいいかもね。
より綺麗な方法が導入されるのはいいんだけど、
過去の方法が消えてなくなるわけでもないし完全に置き換えられるわけでもないからなぁ。
個々には良くなっても全体としては余計に複雑になるだけってのもよくある話。
https://m.xkcd.com/927/
295デフォルトの名無しさん (ワッチョイ c997-trtU)
2023/06/22(木) 09:50:22.29ID:+UOgHQ6A0 max RSS (メモリ総量) の取得ってWindowsとLinuxでポータブルな方法ないの?
296デフォルトの名無しさん (スプッッ Sd12-9xvA)
2023/06/22(木) 10:07:05.02ID:T+/An9G4d C++標準ライブラリには無い
外部ライブラリに頼るか自分で実装するかになるけど、結局のところ#ifdefでOS依存の機能を呼び分けるしかない
外部ライブラリに頼るか自分で実装するかになるけど、結局のところ#ifdefでOS依存の機能を呼び分けるしかない
297デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/22(木) 10:35:39.47ID:myrOOi5M0 std::uintptr_t get_available_memory();
とプロトタイプだけ用意して、定義を環境別に作るだな
内容的に割と単純な処理のはずで
環境別に用意といってもたいした工数にはなるめえよ
とプロトタイプだけ用意して、定義を環境別に作るだな
内容的に割と単純な処理のはずで
環境別に用意といってもたいした工数にはなるめえよ
298デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
2023/06/22(木) 17:54:50.46ID:Sn58Ngpoa Nim いいよね
C++ 嫌になったら Nim においでおいで
C++ 嫌になったら Nim においでおいで
299デフォルトの名無しさん (ワッチョイ c997-trtU)
2023/06/23(金) 06:00:18.48ID:AFPisFIg0 なんかのオブジェクトをポインタじゃなく実体として持ってるとして、それを delete するやり方ってないの?
たとえば std::vector A に対して
delete &A;
みたいな
たとえば std::vector A に対して
delete &A;
みたいな
300デフォルトの名無しさん (ワッチョイ 92ad-DGQF)
2023/06/23(金) 06:14:43.58ID:Dz+tkRpF0 「実体を持っている」と言うが「誰が」持っているかにもよる
グローバル変数として宣言しているなら予めメモリ上に確保されているから破棄は無理(強引に再利用はできる)
スコープ内で変数として宣言したのなら必要なメモリはスタック上にあるからスタックを弄るしかない
別のオブジェクトのメンバ変数として宣言されているならそのオブジェクトを破棄する
グローバル変数として宣言しているなら予めメモリ上に確保されているから破棄は無理(強引に再利用はできる)
スコープ内で変数として宣言したのなら必要なメモリはスタック上にあるからスタックを弄るしかない
別のオブジェクトのメンバ変数として宣言されているならそのオブジェクトを破棄する
301デフォルトの名無しさん (ワッチョイ 92ad-DGQF)
2023/06/23(金) 06:17:44.59ID:Dz+tkRpF0 スコープ内でってのはローカル変数の意味で言ったの
302デフォルトの名無しさん (ワッチョイ 3602-Ul6j)
2023/06/23(金) 07:14:23.97ID:GEB8UNzF0 A.~vector<>();でいいんじゃないの?
メモリ解放が必要ならdelete(void*)&A;とかして。
メモリ解放が必要ならdelete(void*)&A;とかして。
303デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/23(金) 07:18:45.05ID:v++V1HM40 >>299
deleteはdynamic storage durationのオブジェクトにのみ許される
std::vector<int> A;はautomatic storage durationの場合はその定義を囲むブレースから逸脱すれば破棄される
static storage durationの場合はプログラムの実行終了時に破棄される
thread storage durationの場合はスレッド終了時に破棄される
deleteはdynamic storage durationのオブジェクトにのみ許される
std::vector<int> A;はautomatic storage durationの場合はその定義を囲むブレースから逸脱すれば破棄される
static storage durationの場合はプログラムの実行終了時に破棄される
thread storage durationの場合はスレッド終了時に破棄される
304デフォルトの名無しさん (テテンテンテン MM96-Axrn)
2023/06/23(金) 07:19:36.07ID:pmKt7pYtM 極論すれば、c++の変数は自動変数しか無いから、変数で定義しているものはコンパイラに任せるしか無い。
305デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/23(金) 07:23:15.08ID:v++V1HM40 > c++の変数は自動変数しか無い
???
???
306デフォルトの名無しさん (ワッチョイ adc9-1tDD)
2023/06/23(金) 08:10:40.98ID:Z0FiiE+w0 変数の生命期間よりも前に絶つのは new したものを delete する方法しかないよ
std::vector* pA = new std::vector();
std::vector& A = *pA;
:
Aで操作
:
delete pA;
この後 Aに対して操作すると鼻から悪魔
std::vector* pA = new std::vector();
std::vector& A = *pA;
:
Aで操作
:
delete pA;
この後 Aに対して操作すると鼻から悪魔
307デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/23(金) 08:36:05.01ID:v++V1HM40 auto&& A { *new std::vector<int>(0) };
delete &A;
これで「実体」のように偽装はできるけど
こんなコード書くやついたらグーパンだよ
delete &A;
これで「実体」のように偽装はできるけど
こんなコード書くやついたらグーパンだよ
308デフォルトの名無しさん (ワッチョイ 92f0-L1I+)
2023/06/23(金) 08:38:29.90ID:OoWAXDqh0 このスレ読んでると目の裏がチカチカしてくるなw
309デフォルトの名無しさん (ワッチョイ f59c-Axrn)
2023/06/23(金) 08:46:52.36ID:z+mnuoLR0310デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/23(金) 09:45:42.49ID:v++V1HM40 反例っておまえ・・・
静的変数
静的変数
311デフォルトの名無しさん (ワッチョイ 0d4e-L1I+)
2023/06/23(金) 10:11:58.67ID:Zb3L9Wmq0 >>299
deleteで何をしたいかによるな
deleteは
・デストラクタを呼び出して
・メモリを開放する
という2つの動作が含まれるが、「メモリを開放する」に関しては、確保されてもいないメモリはもちろん開放できないが、
デストラクタは実体としてはただの関数なので、普通に呼び出すことは可能
ただし、メモリが開放される(deleteされる)時にもデストラクタはもちろん呼び出されるので、2重に呼び出しても大丈夫なように設計されたクラスである必要はある
deleteで何をしたいかによるな
deleteは
・デストラクタを呼び出して
・メモリを開放する
という2つの動作が含まれるが、「メモリを開放する」に関しては、確保されてもいないメモリはもちろん開放できないが、
デストラクタは実体としてはただの関数なので、普通に呼び出すことは可能
ただし、メモリが開放される(deleteされる)時にもデストラクタはもちろん呼び出されるので、2重に呼び出しても大丈夫なように設計されたクラスである必要はある
312デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/23(金) 11:56:54.20ID:jOpqVfQE0 >>299
スコープを終わらせれば消える
スコープを終わらせれば消える
313デフォルトの名無しさん (テテンテンテン MM96-UmNC)
2023/06/23(金) 13:49:52.85ID:RsoTpuHzM Windows11でc++の開発したいんですけど開発環境何を選べばいいですか?
ちなみに趣味でおもちゃ言語のコンパイラを書こうと思います
ちなみに趣味でおもちゃ言語のコンパイラを書こうと思います
314デフォルトの名無しさん (スッップ Sdb2-Ul6j)
2023/06/23(金) 14:29:49.42ID:P5Uu3Ce/d wslのclangでいいんじゃないの
315デフォルトの名無しさん (ワッチョイ 515f-C6j3)
2023/06/23(金) 14:40:39.89ID:79pDbKtj0 >>311
> 2重に呼び出しても大丈夫なように設計されたクラスである必要はある
trivial destructor 以外は(空の ~T() {} 含め)どうがんばっても大丈夫にはならず未定義動作となる模様。
https://timsong-cpp.github.io/cppwp/n4868/basic.life#9.sentence-1
> 2重に呼び出しても大丈夫なように設計されたクラスである必要はある
trivial destructor 以外は(空の ~T() {} 含め)どうがんばっても大丈夫にはならず未定義動作となる模様。
https://timsong-cpp.github.io/cppwp/n4868/basic.life#9.sentence-1
316デフォルトの名無しさん (テテンテンテン MM96-UmNC)
2023/06/23(金) 14:42:57.84ID:XaN8/xk5M317はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/23(金) 14:49:06.12ID:Xemzxb7u0 >>316
依存するかしないかはプログラマが気を付けることだろ
依存するかしないかはプログラマが気を付けることだろ
318デフォルトの名無しさん (ワッチョイ 196e-ljvc)
2023/06/23(金) 14:58:36.88ID:v++V1HM40319はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/23(金) 15:11:25.32ID:Xemzxb7u0 俺はコンパイラは複数を利用するのが好ましいと思う。
気を付けてても処理系に依存している (または未定義を踏んでいる) こともある。
いくつかのコンパイラで試してみれば問題点を発見しやすい。
発現した問題についてはデバッガなりなんなりで追えばいいんだが、
問題が潜伏したまま表面に現れないってのは後になってじわじわ効いてきたりするし……。
気を付けてても処理系に依存している (または未定義を踏んでいる) こともある。
いくつかのコンパイラで試してみれば問題点を発見しやすい。
発現した問題についてはデバッガなりなんなりで追えばいいんだが、
問題が潜伏したまま表面に現れないってのは後になってじわじわ効いてきたりするし……。
320デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
2023/06/23(金) 16:11:46.79ID:lCxAQSJFa >>299
デストラクタに直接リソース解放させるより
リソース解放用の dispose() みたいな関数を造っておいて
デストラクタから dispose() 呼ぶのと同時に
delete しないで dispose() だけ外から呼ぶ設計もあるよ
デストラクタに直接リソース解放させるより
リソース解放用の dispose() みたいな関数を造っておいて
デストラクタから dispose() 呼ぶのと同時に
delete しないで dispose() だけ外から呼ぶ設計もあるよ
321デフォルトの名無しさん (アウアウウー Sacd-Hkv7)
2023/06/23(金) 16:14:47.39ID:lCxAQSJFa >>313
Code::Blocks (+ mingw)
Code::Blocks (+ mingw)
322デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/23(金) 18:47:00.64ID:5tcqgCxE0 コンパイラの本なにがいいのかオススメ聞いたらオッサンに聞いたら怪獣が書いてある本って云われて本屋行って買ったらあとで付録のFDD誰かにかっぱわられていタコとに気付いたけどその本一冊ではなんの役にも立たないクソみたいな本だったわ
そのあとオライリーのyacc&lexの本と早乙女氏のBison&Flex本で学び直したわ
そのあとオライリーのyacc&lexの本と早乙女氏のBison&Flex本で学び直したわ
323デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/23(金) 19:05:06.07ID:5tcqgCxE0324デフォルトの名無しさん (テテンテンテン MM96-Axrn)
2023/06/23(金) 19:51:54.58ID:s3XGk2XtM325はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/23(金) 22:40:53.53ID:Xemzxb7u0 >>324
???
storage duration は四種類の内の「ひとつ」であることは直接的に明記されていて解釈の余地がない。
https://timsong-cpp.github.io/cppwp/n4861/basic.stc#1
兼ねる場合は存在しない。
???
storage duration は四種類の内の「ひとつ」であることは直接的に明記されていて解釈の余地がない。
https://timsong-cpp.github.io/cppwp/n4861/basic.stc#1
兼ねる場合は存在しない。
326デフォルトの名無しさん (ワッチョイ 6501-2DXs)
2023/06/24(土) 08:29:33.32ID:31MSzc3x0 >まず動くものを作ることに注力したほうがいい。
+1票
>いくつかのコンパイラで試してみれば問題点を発見しやすい。
これはその通りだけど、もっともっと先の話
+1票
>いくつかのコンパイラで試してみれば問題点を発見しやすい。
これはその通りだけど、もっともっと先の話
327デフォルトの名無しさん (ワッチョイ 856e-gmRT)
2023/06/24(土) 09:51:19.10ID:xNNc2oEW0 動くといってもHello worldじゃあまりにもモチベーションに乏しいから
何でもいいから目的目標を持ったプログラムを書いたほうがいい
何でもいいから目的目標を持ったプログラムを書いたほうがいい
328はちみつ餃子 ◆8X2XSCHEME (ワッチョイ dd3e-F8yx)
2023/06/24(土) 12:57:29.18ID:rXisqo0O0329デフォルトの名無しさん (ワッチョイ 6501-wYA+)
2023/06/24(土) 20:48:58.11ID:rm+SB6K20 ドラゴンブックでは?
誤植を指摘できるくらい読み込めば古典は理解できてると思う
誤植を指摘できるくらい読み込めば古典は理解できてると思う
330デフォルトの名無しさん (アウアウウー Sa69-F3wx)
2023/06/27(火) 14:41:09.50ID:DdZG5nY/a いつまでも初心者を抜け出せない人は初心者本を読み過ぎ
331デフォルトの名無しさん (ワッチョイ 856e-gmRT)
2023/06/27(火) 17:36:09.51ID:59BI4JPS0 初心者本は【ど】初心者のうちだけにしとけ
謙虚なことはいいことだが、ここだけは背伸びしたほうがいい
初心者本で何か知ったら、それで禿本がどのくらい読めるようになったかやってみれ
禿本が普通に読めるようになったら次はISOの規格票
謙虚なことはいいことだが、ここだけは背伸びしたほうがいい
初心者本で何か知ったら、それで禿本がどのくらい読めるようになったかやってみれ
禿本が普通に読めるようになったら次はISOの規格票
332デフォルトの名無しさん (ワッチョイ 856e-gmRT)
2023/06/27(火) 17:38:22.91ID:59BI4JPS0 逆もしかり
ISOの規格票であえなくギブしたら禿本
禿本でギブのとき初心者本に戻る感じな
ISOの規格票であえなくギブしたら禿本
禿本でギブのとき初心者本に戻る感じな
333デフォルトの名無しさん (ワッチョイ 8d7c-BujW)
2023/06/27(火) 18:00:18.69ID:h1cnuIf90 特にC++は下手な参考書より規格の方が分かりやすかったりするからな…
334デフォルトの名無しさん (ワッチョイ dd4e-OfpS)
2023/06/27(火) 18:15:38.33ID:D2orubkn0 初心者へのアドバイスに禿本とかいう隠語をつかうのはどうかと思う
335デフォルトの名無しさん (ワッチョイ d5b3-q57E)
2023/06/27(火) 18:27:04.42ID:KKkR5HKI0 今独学でC++学んでいるんですが、たまたま見つけたサイトでint32_tとありましたが
int変数を宣言するのにint32_tなんて使いませんよね?
intでokですよね?
int変数を宣言するのにint32_tなんて使いませんよね?
intでokですよね?
336デフォルトの名無しさん (ワッチョイ ad5f-VF0j)
2023/06/27(火) 18:34:12.56ID:3myjDgNL0 何に使うか次第
337デフォルトの名無しさん (ワッチョイ ad02-ES2+)
2023/06/27(火) 18:46:35.68ID:gpD88JT50 >>335
32ビット長である必要があるときだけint32_tを使えばいいよ
32ビット長である必要があるときだけint32_tを使えばいいよ
338デフォルトの名無しさん (ワッチョイ d5b3-q57E)
2023/06/27(火) 19:26:51.01ID:KKkR5HKI0 サンクス
339はちみつ餃子 ◆8X2XSCHEME (ワッチョイ dd3e-F8yx)
2023/06/27(火) 19:30:48.55ID:wxXBe/Gr0 >>335
int は言語仕様では少なくとも -32767 から 32767 を表現可能な幅 (つまり 16 ビット) を持つことが規定されている。
具体的な大きさは処理系定義であって、最低限である 16 ビットかもしれないしもっと大きいかもしれない。
扱おうとする値の範囲が 32 ビット分の幅が必要であると見積もったなら int32_t が適切なこともある。
ただ…… int32_t は「条件に合致する整数型を処理系が持っているなら必ず提供しなければならない」ということになっているので、逆に言えば 32 ビット幅の整数型を持たない処理系では int32_t が存在しないことが許される。
C++ は処理系定義ということにしている項目がたくさんあって移植性を考慮しようとするとすごく大変なんだが (プログラマが想定してさえいれば) ある程度に広く対応可能な仕組みとしてこういう回りくどいものがある。
初心者の内はとりあえず自分の環境で動くものを作れるようになるというので十分だと思うよ。
int は言語仕様では少なくとも -32767 から 32767 を表現可能な幅 (つまり 16 ビット) を持つことが規定されている。
具体的な大きさは処理系定義であって、最低限である 16 ビットかもしれないしもっと大きいかもしれない。
扱おうとする値の範囲が 32 ビット分の幅が必要であると見積もったなら int32_t が適切なこともある。
ただ…… int32_t は「条件に合致する整数型を処理系が持っているなら必ず提供しなければならない」ということになっているので、逆に言えば 32 ビット幅の整数型を持たない処理系では int32_t が存在しないことが許される。
C++ は処理系定義ということにしている項目がたくさんあって移植性を考慮しようとするとすごく大変なんだが (プログラマが想定してさえいれば) ある程度に広く対応可能な仕組みとしてこういう回りくどいものがある。
初心者の内はとりあえず自分の環境で動くものを作れるようになるというので十分だと思うよ。
■ このスレッドは過去ログ倉庫に格納されています
