我开发一个项目,该项目有多个算术类型的作品。 所以,我提出的报头,其中,被定义为用户定义的算术类型的最低要求:
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>
。 是不是有什么错在这里,或我误解的东西吗?
C ++标准库的实施方式允许在全局命名空间以及在声明C库函数std
。 有人会称这是一个错误,因为(如你发现)的命名空间的污染可能会导致自己的名字的冲突。 然而,这事情是这样的,所以我们必须忍受它。 你只需要符合您的姓名作为arithmetic::sin
。
在标准的(C ++ 11 17.6.1.2/4)的话:
在C ++标准库,但是,声明(除了其被定义为在C宏名称)是命名空间的命名空间范围(3.3.6)内std
。 它是不确定是否这些名称是全局命名空间范围内首先声明 ,然后通过使用明确的-声明(7.3.3)注入空间std。
如果你真的想,你总是可以写身边一个小包装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;
}
我想可能有一些开销,从附加功能调用,这取决于编译器如何聪明之处。
这仅仅是一个不起眼的尝试,开始解决这个问题。 (建议是欢迎。)
我一直在处理这个问题很长一段时间。 的情况是:这个问题是非常明显的是这种情况:
#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
}