我正在编写一个表示算术类型的 C++ 类(围绕 mpfr 的 C++ 包装器),我想支持
所以我有以下类(class):
namespace ns
{
class MyClass
{
/* ... */
public:
friend MyClass sqrt(const MyClass& mc);
};
}
我可以这样使用它:
MyClass c;
/* ... */
MyClass d = ns::sqrt(c);
MyClass e = sqrt(c); // Apparently I don't have to specify ns::
但我不能这样使用它:
MyClass f = std::sqrt(c);
编译器 (g++ (Debian 4.7.2-5)) 错误是:“没有匹配函数调用 sqrt(ns::MyClass&)”。
这很正常,但对我来说是个问题。我需要它是有效的,因为 MyClass 应该用于现有的模板函数(我不应该修改)。例如:
template <typename T>
void func(T a)
{
/* ... */
T c = std::sqrt(a);
/* ... */
}
int main()
{
func<float>(3);
func<MyClass>(MyClass(3));
/* ... */
}
下面这段代码实际上解决了我的问题:
namespace std
{
using ns::sqrt;
}
但在 std 命名空间中添加东西对我来说似乎很不自然。这样做我怕以后会遇到意想不到的麻烦。
安全吗?如果不是,为什么?
还有更好的选择吗?
最佳答案
标准禁止向命名空间 std
添加内容。解决这个问题的正确方法通常是 swap
(在 std
命名空间中可用,但可以通过用户定义的类型进行专门化以更有效地工作) :当需要使用模板函数时,例如sqrt
,就可以了
using std::sqrt;
a=sqrt(b);
这样,对于“常规”类型,它将使用 std::sqrt
(通过 using
语句“接受”),而对于您的类型,您的重载将以Koenig lookup为准(顺便说一句,这就是您在 //显然我不必指定 ns::
处观察到的行为的原因)。
关于c++ - 在 C++ 中重载命名空间 std 中的数学函数是一种好习惯吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22701354/