为什么命名空间内的自由函数是模糊的?

时间:2014-03-08 00:19:22

标签: c++ gcc

- myfunc.hh

#ifndef MY_FUNC_HH
#define MY_FUNC_HH

namespace abc
{
int xyz (int a, int b);
}

#endif

- myfunc.cc

#include "myfunc.hh"

using namespace abc;

int xyz (int a, int b)
{
    if (!b)
        return 0;
    return xyz (b, b/a);
}

$ g++ -c -g myfunc.cc myfunc.hh

myfunc.cc: In function ‘int xyz(int, int)’:
myfunc.cc:9: error: call of overloaded ‘xyz(int&, int)’ is ambiguous
myfunc.cc:5: note: candidates are: int xyz(int, int)
myfunc.hh:6: note:                 int abc::xyz(int, int)

为什么xyz在这里只定义了一个名为xyz的函数时会重载?

不是using namespace abc告诉编译器在命名空间abc中查找名称xyz? 例如,当您使用std :: copy函数

#include <algorithm>
using namespace std;

void afunction()
{
   copy(blah, blah, blah);
}

一切正常,为什么abc :: xyz在这里有什么不同?或者,是因为递归调用?如果是这样,为什么?

4 个答案:

答案 0 :(得分:4)

我想在myfunc.cc中你要写

#include "myfunc.hh"

namespace abc {

int xyz (int a, int b)
{
    if (!b)
        return 0;
    return xyz (b, b/a);
}

}

这样您定义您在abc::xyz文件中声明的.h函数。您编写它的方式是在命名空间xyz之外定义abc函数,同时还导入在命名空间中声明的函数。因此含糊不清。

同意@cHao和@JonathanWakely的建议,我赞成这种更好的语法:

int abc::xyz (int a, int b)
{
    if (!b)
        return 0;
    return xyz (b, b/a);
}

确实,它确保在头文件中正确声明了abc::xyz

答案 1 :(得分:1)

myfunc.cc文件中,您重载了xyz函数。这意味着您正在定义一个全新的功能。全局命名空间中有一个 local ,命名空间abc中有一个。

您的示例中的语句using namespace abc;实际上引入了歧义,而不是解决它。在编译器不知道要调用哪个函数的意义上,您的调用是不明确的。

答案 2 :(得分:1)

这两个代码之间存在差异:

- myfunc.cc

#include "myfunc.hh"

using namespace abc;

int xyz (int a, int b)
{
    if (!b)
        return 0;
    return xyz (b, b/a);
}

- myfunc.cc

#include "myfunc.hh"

namespace abc {

int xyz (int a, int b)
{
    if (!b)
        return 0;
    return xyz (b, b/a);
}

}

第一个使用abc命名空间,但xyz在“top”命名空间中定义;有两个功能定义。第二部分给出了abc::xyz函数的实现。

在你的情况下,你想要做第二次。

答案 3 :(得分:0)

您的问题似乎在问为什么当您明确告诉编译器使xyz(int, int)可见并然后定义另一个版本时,有两个xyz(int, int)版本可见?

您希望编译器在这里做什么?它不会为你猜测,所以它会给你一个错误。

如果需要调用其中一个,请使用范围运算符和显式命名空间。例如,您可以拨打::xyz(1, 2)abc::xyz(1, 2)