代码之家  ›  专栏  ›  技术社区  ›  Dan Olson

过载分辨率中的常量指针

  •  5
  • Dan Olson  · 技术社区  · 15 年前

    GCC将这两个函数声明视为等效的:

    void F(int* a) { }
    void F(int* const a) { }
    

    test.cpp:在函数“void f(int*)”中:

    test.cpp:235:错误:重新定义“void f(int*)”

    test.cpp:234:错误:“void f(int*)”以前在此处定义

    这是有道理的,因为在这种情况下,调用者总是忽略常量…它只影响函数内部参数“a”的使用。

    我想知道的是,标准在哪里(如果有的话)说,为了过载解析的目的,放弃指针上用作函数参数的限定符是特别合适的。

    (我真正的问题是,我想弄清楚GCC是如何在内部剥离这些毫无意义的限定符的,因为GCC的C++前端散布着引用标准的评论,标准的相关部分可能会帮助我找到正确的点。)

    4 回复  |  直到 14 年前
        1
  •  4
  •   AnT stands with Russia    14 年前

    标准在8.3.5/3中说 用于确定功能类型 将删除直接限定参数类型的任何CV限定符。也就是说,它字面上说一个函数声明为

    void foo(int *const a);
    

    具有函数类型 void (int *) .

    一个学究可能会争辩说,这还不足以证明上述声明应该与这一定义相匹配。

    void foo(int *a)
    {
    }
    

    或者它应该使具有双重声明的代码(如您的示例中所示)格式不正确,因为标准中没有用 功能类型 .

    我是说,我们都知道这些 const 我本打算出于所有外部目的而被忽略,但到目前为止,我无法在标准中找到确切说明这一点的措辞。也许我错过了什么。

    实际上,在13.1/3中,它有一个“注释”,表示具有等效参数声明(如8.3.5中定义)的函数声明声明声明 相同的功能 . 但它只是一个注释,它是非规范性的,这意味着在标准的某个地方,在同一问题上应该有一些规范性的文本。

        2
  •  3
  •   UncleBens    15 年前

    我认为这基本上是禁止的:

    void foo(int a) {}
    void foo(const int a) {}
    

    非引用上的常量不参与重载。

    实际上你甚至可以申报

    void foo(int a);
    

    然后定义

    void foo(const int a) {}
    

    其中consstness纯粹是一个调用方不关心的实现细节。

        3
  •  2
  •   GManNickG    15 年前

    与以下内容相同:

    void foo(int);
    void foo(const int);
    

    与来电者相同。这是因为无论什么函数都按值获取副本,所以调用方不关心它是否被认为是 const 或者没有,这对它没有什么区别。

    它是 对于编译器来说,忽略这样的事情是合法的,但是在重载解析上没有区别。这个 康斯特 适用于功能的实现。

    如果编译器处理以下内容,则为非法:

    void foo(int i)
    {
        i = 5; // good
    }
    
    void foo(const int)
    {
        i = 5; // lolwut?
    }
    

    同样,忽略 康斯特 .

        4
  •  1
  •   Drakosha    15 年前

    我相信是相反的。任何指针,甚至是非指针,都可以被视为const:。