-->

为什么在一些功能上 不是在std命名空间? 为什么在一些功能上 不是在std命名空间?(W

2019-06-02 11:09发布

我开发一个项目,该项目有多个算术类型的作品。 所以,我提出的报头,其中,被定义为用户定义的算术类型的最低要求:

user_defined_arithmetic.h:

typedef double ArithmeticF;   // The user chooses what type he 
                              // wants to use to represent a real number

namespace arithmetic          // and defines the functions related to that type
{

const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}

什么是困扰我的是,当我使用这样的代码:

#include "user_defined_arithmetic.h"

void some_function()
{
    using namespace arithmetic;
    ArithmeticF lala(3);
    sin(lala);
}

我得到一个编译错误:

error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)

我从来没有使用的<math.h>报头,只有<cmath> 我从来没有使用过的using namespace std中的头文件。

我用gcc 4.6。*。 我查了一下是包含模棱两可的声明标题并将其结果是:

mathcalls.h:

Prototype declarations for math functions; helper file for <math.h>.
...

我知道,那<cmath>包括<math.h> ,但应该由std命名空间屏蔽声明。 我挖入<cmath>头和发现:

cmath.h:

...

#include <math.h>

...

// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...

namespace std _GLIBCXX_VISIBILITY(default)
{
...

所以空间std 开始#include <math.h> 。 是不是有什么错在这里,或我误解的东西吗?

Answer 1:

C ++标准库的实施方式允许在全局命名空间以及在声明C库函数std 。 有人会称这是一个错误,因为(如你发现)的命名空间的污染可能会导致自己的名字的冲突。 然而,这事情是这样的,所以我们必须忍受它。 你只需要符合您的姓名作为arithmetic::sin

在标准的(C ++ 11 17.6.1.2/4)的话:

在C ++标准库,但是,声明(除了其被定义为在C宏名称)是命名空间的命名空间范围(3.3.6)内std它是不确定是否这些名称是全局命名空间范围内首先声明 ,然后通过使用明确的-声明(7.3.3)注入空间std。



Answer 2:

如果你真的想,你总是可以写身边一个小包装cmath ,沿着线:

//stdmath.cpp
#include <cmath>
namespace stdmath
{
    double sin(double x)
    {
        return std::sin(x);
    }
}

//stdmath.hpp
#ifndef STDMATH_HPP
#define STDMATH_HPP
namespace stdmath {
    double sin(double);
}
#endif

//uses_stdmath.cpp
#include <iostream>
#include "stdmath.hpp"

double sin(double x)
{
    return 1.0;
}

int main()
{
    std::cout << stdmath::sin(1) << std::endl;
    std::cout << sin(1) << std::endl;
}

我想可能有一些开销,从附加功能调用,这取决于编译器如何聪明之处。



Answer 3:

这仅仅是一个不起眼的尝试,开始解决这个问题。 (建议是欢迎。)

我一直在处理这个问题很长一段时间。 的情况是:这个问题是非常明显的是这种情况:

#include<cmath>
#include<iostream>

namespace mylib{
    std::string exp(double x){return "mylib::exp";}
}

int main(){
    std::cout << std::exp(1.) << std::endl; // works
    std::cout << mylib::exp(1.) << std::endl; // works

    using namespace mylib;
    std::cout << exp(1.) << std::endl; //doesn't works!, "ambiguous" call
    return 0;
}

这在我看来是一个恼人的错误,或者至少一个非常不幸的情况。 (至少在海湾合作委员会,并铛在Linux中--using GCC library--。)

最近我给它一个镜头的问题。 通过查看cmath (的GCC)似乎头是有简单地重载C-功能和螺丝了在这个过程中的命名空间。

namespace std{
   #include<math.h>
}
//instead of #include<cmath>

有了它,这个工程

using namespace mylib;
std::cout << exp(1.) << std::endl; //now works.

我几乎可以肯定,这是不完全等同于#include<cmath>但大多数功能似乎工作。

最糟糕的是,最终一些依赖库终将会#inclulde<cmath> 为此,我无法找到一个解决办法呢。

:不用说,这并不在所有的工作

namespace std{
   #include<cmath> // compile errors
}


文章来源: Why are some functions in not in the std namespace?