这个问题基本上是我给出的这个答案的后果。我刚刚意识到标准中的措辞似乎省略了一些情况。考虑这段代码:
#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)whenf是指向类的成员函数的指针,T并且t1是类型对象T或对类型对象的T引用或对派生于的类型对象的引用T;—
((*t1).*f)(t2, ..., tN)whenf是指向类的成员函数的指针,T并且t1不是上一项中描述的类型之一;—
t1.*f当N == 1andf是指向类的成员数据的指针T并且t1是类型对象T或对类型对象的T引用或对派生于的类型对象的引用时T;—
(*t1).*fwhenN == 1和f是指向类的成员数据的指针,T并且t1不是上一项中描述的类型之一;—
f(t1, t2, ..., tN)在所有其他情况下。
读到这里,第一个列表项似乎允许三种情况:
t1是类型的对象T- 或对类型对象的引用
T - 或对派生自的类型的对象的引用
T
但在我的例子中,两者都不是。它是派生自 的类型T,但没有引用。上面列出的情况不应该是:
t1是类型的对象T- 或派生自的类型的对象
T - 或对类型对象的引用
T - 或对派生自的类型的对象的引用
T
当然,这同样适用于 20.8.2 中的第三个列表项。
问题 1:由于 GCC 和 Clang 都接受我的代码,我想知道这是否是违反标准的缺陷报告,或者我只是读错了。
问题 2:使用多重/虚拟继承,即使一个类型派生自T,也可能无法简单地调用(t1.*f)(...)它,对吗?这也是我应该关注的事情,还是标准在给定的上下文中清楚地定义了“源自”?