5
struct A
{
    enum InnerEnum { X };

    A(InnerEnum x)
    {}
};

int main()
{
    A a(X);
}

编译器抱怨:error C2065: 'X' : undeclared identifier

编译器知道构造函数的参数类型是什么,所以当我将 X 作为参数传递时,编译器应该知道它是一个有效参数。

我知道这不是 ADL(Argument-dependent Name Lookup,也称为 Koenig Lookup),但我认为它很有用且非常方便。因为我不必写如下:

A a(A::X);

我认为 ADL 规则应该推广到这种情况。

我对吗?

4

2 回答 2

10

C++ 中的函数调用受函数重载决议的约束。重载决议由参数类型驱动。即语言专门在那个方向“起作用”:参数类型具有给定名称的函数的特定版本。

您提议引入一个反向过程 - 基于函数名称的参数类型推导。这在一般情况下不起作用。它可能在只有一个候选函数(如您的示例中)的情况下起作用,但同样,这与在函数重载时的一般情况下起作用的原则相反。

当然,当对非限定名称X进行名称查找时X,除了您的A::X. 我认为它很容易变得非常违反直觉。

于 2013-01-04T19:46:13.063 回答
4

我认为 ADL 规则应该推广到这种情况。

不,谢谢。

C++ 有一些(令人讨厌的)惊喜(您知道哪种其他语言需要explicit作为关键字?),我认为您的示例没有足够的优点添加到这个意外语言规则列表中,这些规则会在意外情况下阻碍我的代码。

如果您发现在 class-name 后面加上两个冒号需要额外的输入,那么 C++ 语法的一般巴洛克性质现在肯定会让您失望吗?

于 2013-01-04T19:47:00.963 回答