gpt4 book ai didi

c++ - 在命名空间 std 中重载函数模板

转载 作者:行者123 更新时间:2023-12-04 14:56:57 24 4
gpt4 key购买 nike

这里有关于函数特化的讨论:Will specialization of function templates in std for program-defined types no longer be allowed in C++20?

原则上我理解,重载比专门化更好。但是如何正确地重载标准函数模板呢?规范的答案似乎是:只需在您的自定义命名空间中重载,然后 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 中,我没有找到关于这个方向的提示。虽然这个paper Walter E. Brown 的作者提出重载作为特化的替代方案,我不确定上面的例子是否正确使用了它(论文没有给出任何例子)。

最佳答案

不允许将 sqrt 的重载添加到 std 命名空间。

但是,您可以使用完全限定名称,或者通过添加 using std::sqrt 来赋予 std::sqrt 首选项:

#include <cmath>

namespace X {

class Y { };

Y sqrt(Y) { return {}; }

double foo(double x) {
return std::sqrt(x);
}

} // namespace X

template <typename T>
T bar(T x){
using std::sqrt;
return sqrt(x);
}

double baz(double x){
using std::sqrt;
return sqrt(x);
}

double moo(double x){
return bar(x);
}

X::Y zoo(X::Y x){
return bar(x);
}

请注意,std::sqrt 禁用 ADL,而 使用 std::sqrt 仍允许 ADL 启动,如 bar 所示这是从 moozoo 调用的。

关于c++ - 在命名空间 std 中重载函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67772654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com