为什么C++11不支持这样的名称查找?

5
struct A
{
    enum InnerEnum { X };

    A(InnerEnum x)
    {}
};

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

编译器报错:error C2065: 'X' : 未声明的标识符

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

我知道这不是 ADL(依赖参数名查找,也称为 Koenig 查找),但我认为它很有用且方便。因为我不必写成下面这样:

A a(A::X);

我认为ADL规则应该推广到这种情况。
我说得对吗?

2
这就像是 ADL 的反向操作... FDL(函数相关查找)。 - Seth Carnegie
9
你是否考虑过当你也有一个名为X的本地变量时,这将如何应用?无论如何,从我的阅读中来看,你是在说这是无效的C++,并询问C++标准是否应该更改。这不是讨论的正确场所。 - user743382
谢谢,hvd。你给了我们一个令人信服的理由。 - xmllmx
2
如果你在问标准是否有误,那么不是的;这就是为什么它是标准。你认为它非常不方便是另外一个问题。你的构造函数需要一个 A::InnerEnum 值作为参数。该枚举定义在 A 的命名空间范围内,在访问其外部时需要解析。 - WhozCraig
2个回答

10
在C++中,函数调用需要进行函数重载解析。重载解析由参数类型驱动。也就是说,语言“工作”在这个方向上:从参数类型到具有给定名称的特定版本函数。

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

当未限定名称X的名称查找除了您的A::X之外还可以看到其他命名为X的内容时,情况会变得更加复杂。我认为它很容易变得非常难以理解。

我理解一般情况下适用的复杂性论点。因此,也许不是一般情况,但出于某种原因,我认为这对于“枚举”特别有用。因为它们经常作为函数的任意命名选项。 - alfC

4

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

不,谢谢。

C++ 有其自己的(令人讨厌的)惊喜(你知道其他哪种语言需要使用 explicit 作为关键字吗?),而且我没有看到足够的优点来将您的示例添加到这个意外的语言规则列表中,从而阻碍我的代码在意想不到的情况下。

如果您觉得类名后跟两个冒号所需的额外输入过于繁琐,那么 C++ 语法的一般花哨应该已经让您望而却步了吧?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接