std::is_invocable
に関数としてクラスメンバへのポインタを与えるとき、その引数として最初に与えるクラス自身の型はどのようにするのが仕様的に良いのでしょうか?
cpp
1#include <type_traits> 2 3struct cls { 4 int mem_fn(); 5}; 6 7static_assert(std::is_invocable_v<decltype(&cls::mem_fn), /* cls, cls&, cls*, etc. */>); 8 9int main() {}
libstdc++のソースを読んだ限り、const
修飾子の有無(const
修飾されたメンバ関数の場合)、参照の有無、ポインタの有無で挙動は変わらないようなので、どの型がメンバポインタをとるときの仕様として理想的なのか分かりかねています。
より詳細はWandoxで確認いただければと。
回答よろしくお願いします。
追記
yohhoy様
「仕様的に良い」「仕様として理想的」は、どのようなニュアンス・観点を指していますか?
言葉が足らず申し訳ないです。
まず、クラスメンバを呼び出す際、メンバ関数(あるいはメンバ変数も)の隠し引数としてオブジェクトのアドレスが渡される(これがthis
ポインタとして扱われる)と、一般に理解されていると思います。
cpp
1cls c; 2c.mem_fn(); // -> mem_fn(&c);
でしたら、
cpp
1is_invocable_v<decltype(&cls::mem_fn), cls*>
という形が想定されるべき「仕様」なのではと考えました。
ところが実際は、cls*
は内部的に->*
演算子を使ってチェックする特殊化がなされ、cls
やcls&
などは内部的にconst
修飾子や参照が取り除かれたの上で.*
演算子を使ってチェックする特殊化がなされているようなので、結果に違いがありませんでした。
したがって、凡そどの型でも構わないようであれば、与えられるべき型の「仕様」は特に定まっていないのだろうかと疑問に思った次第です。
ニュアンスは伝わりましたでしょうか?
(もしかして「特に定まっていない」で結論なのでは…)
回答1件
あなたの回答
tips
プレビュー