【发布时间】:2021-05-31 11:13:40
【问题描述】:
这里有关于函数特化的讨论:Will specialization of function templates in std for program-defined types no longer be allowed in C++20?
原则上我理解,重载而不是专门化更好。但是如何正确地重载 std 函数模板呢? 规范的答案似乎是:只需在您的自定义命名空间中重载,然后 ADL 就会启动。但是,如果涉及基本类型,这不起作用。非工作示例:
#include <cmath>
namespace X {
class Y { };
Y sqrt(Y);
double foo(double x) { return sqrt(x); }
}
该示例只会在没有 Y 的 sqrt 声明的情况下编译。可以通过在命名空间 std 中重载来解决此问题:
#include <cmath>
namespace X {
class Y { };
}
namespace std { X::Y sqrt(X::Y); }
namespace X {
double foo(double x)
{
return sqrt(x);
}
}
这段代码正是我想做的。但是我不确定标准是否允许这种重载。在 cppreference 我没有找到指向这个方向的提示。虽然 Walter E. Brown 的 paper 提出重载作为专业化的替代方案,但我不确定上述示例是否正确使用(论文没有给出任何示例)。
【问题讨论】:
-
在
foo内调用std::sqrt(x);或using std::sqrt有什么问题? -
关于
std::sqrt(x);见下文。在你的代码中到处写using std::sqrt(sin,exp aso)只是为了重新激活基本类型的标准函数,感觉就像是一个语言缺陷。 -
#include <cmath>不必将sqrt等引入全局命名空间。您的实现出于某种原因这样做,但这不是语言所保证的。通常你应该到处调用std::sqrt,或者说using std::sqrt,不管你是否定义了自己的sqrt。 -
关于“见下文”,我从下面来,希望在这里得到一个提示,问题到底是什么。你似乎期待
std::sqrt是它不是的东西。你想要别的东西,所以你需要做一些额外的事情。这不是语言缺陷,如果std::sqrt可以调用任何东西,我宁愿将其视为语言缺陷,但不能保证是std::sqrt。
标签: c++ overloading std c++20 function-templates