为什么从同一命名空间中的同名成员函数调用全局函数时必须指定该全局函数的命名空间?

问题描述 投票:0回答:1

我有三个 C++ 文件

header1.h
header2.h
main.cpp
。它们如下:

header1.h
,在命名空间
lerp
中定义了函数
MyNamespace

#ifndef HEADER_1_H
#define HEADER_1_H

namespace MyNamespace {

    template <typename T>
    inline float lerp(float t, T a, T b) {
        return (1 - t) * a + t * b;
    }

};

#endif

header2.h
,在
MyClass
中定义了一个类
MyNamespace
,该类有一个名为
lerp
的成员函数,它从
lerp
调用
header1.h

#ifndef HEADER_2_H
#define HEADER_2_H

#include "header1.h"

namespace MyNamespace {

    struct MyClass {
        float x, y, z;
    
        void lerp(float t) {
            x = lerp(t, x, 0.f);
             // ^^ This results in a compiler error (no matching function for
             // call to ‘MyNamespace::MyClass::lerp(float&, float&, float). Why?
             // Also, either prefixing this `lerp` with MyNamespace, or changing
             // the name of this member function to anything else that's not lerp,
             // stops the compiler error from occurring. Why?
        }
    };

};

#endif

main.cpp
,构造一个类型为
MyClass
的对象并在其上调用
MyClass::lerp()

#include "header2.h"

using namespace MyNamespace;

int main()
{
    MyClass mc{1, 2, 3};
    mc.lerp(4);  // results in a compiler error; see the comment in "header2.h"

    return 0;
}

当我尝试编译

main.cpp
时,我收到以下关于我在
lerp
中的
MyClass::lerp()
函数中使用
header2.h
的编译器错误:

header2.h: In member function ‘void MyNamespace::MyClass::lerp(float)’:
header2.h:12:17: error: no matching function for call to ‘MyNamespace::MyClass::lerp(float&, float&, float)’
   12 |         x = lerp(t, x, 0.f);
      |             ~~~~^~~~~~~~~~~
header2.h:11:10: note: candidate: ‘void MyNamespace::MyClass::lerp(float)’
   11 |     void lerp(float t) {
      |          ^~~~
header2.h:11:10: note:   candidate expects 1 argument, 3 provided

所以,我的第一个问题是,为什么编译器似乎无法找到

MyNamespace::lerp()
中提供的
header1.h
的定义?
不应该找到吗,因为我们在同一个命名空间 (
MyNamespace
) 并且因为
header2.h
包含
header1.h
?

此外,我还观察到,无论是使用

lerp(t, x, 0.f)
显式限定
MyNamespace
,还是通过将成员函数
MyClass::lerp
重命名为其他任何名称,编译器错误都会消失。这是为什么?

c++ compiler-errors c++20 header-files
1个回答
0
投票

为什么编译器似乎无法找到 header1.h 中提供的 MyNamespace::lerp() 的定义?

因为当您编写

x = lerp(t, x, 0.f);
时,搜索查找开始并找到名为
lerp
的成员函数,因此查找停止。因此,唯一的候选函数是名为
lerp
的成员函数。由于它与调用参数不兼容,我们收到了上述错误。

© www.soinside.com 2019 - 2024. All rights reserved.