この質問は基本的に、私が与えたこの回答の余波です。標準の文言では、いくつかのケースが省略されているように見えることに気付きました。次のコードを検討してください。
#include <iostream>
#include <functional>
struct foo
{
void f(int v) { std::cout << v << std::endl; }
};
struct bar : foo {};
int main()
{
bar obj;
std::bind(&foo::f, obj, 1)();
}
標準では、20.8.9.1.2 で、その効果とstd::bind、それが呼び出されたときに何が起こるかについて説明しています。20.8.2 に転送されます。関連する部分は次のとおりです。
20.8.2 要件 [func.require]
1 INVOKE
(f, t1, t2, ..., tN)を次のように定義します。—
(t1.*f)(t2, ..., tN)がfクラスのメンバ関数へのポインタでありT、t1型Tのオブジェクト、型のオブジェクトへのT参照、または から派生した型のオブジェクトへの参照である場合T。—
((*t1).*f)(t2, ..., tN)がfクラスのメンバ関数へのポインタでありT、t1前の項目で説明した型のいずれでもない場合。—および
t1.*fがクラスのメンバ データへのポインタであり、が型のオブジェクト、または型のオブジェクトへの参照、または から派生した型のオブジェクトへの参照である場合。N == 1fTt1TTT— and
(*t1).*fがクラスのメンバ データへのポインタであり、前の項目で説明した型のいずれでもない場合。N == 1fTt1—
f(t1, t2, ..., tN)その他のすべての場合。
これを読むと、最初のリスト項目に 3 つのケースが許可されているようです。
t1型のオブジェクトですT- または型のオブジェクトへの参照
T - またはから派生した型のオブジェクトへの参照
T
しかし、私の例では、どちらでもありません。から派生した型Tですが、参照はありません。上記のケースは次のとおりではありません。
t1型のオブジェクトですT- またはから派生した型のオブジェクト
T - または型のオブジェクトへの参照
T - またはから派生した型のオブジェクトへの参照
T
もちろん、同じことが 20.8.2 の 3 番目のリスト項目にも当てはまります。
質問 1: GCC と Clang の両方が私のコードを受け入れるので、これは標準に対する欠陥レポートなのか、それとも私の読み方が間違っているだけなのか疑問に思います。
質問 2:多重/仮想継承では、型が から派生したものであっても、T単純に呼び出すことができない場合があり(t1.*f)(...)ますよね? それも私が懸念すべきことですか、それとも標準は特定のコンテキストで「派生元」を明確に定義していますか?