如何解决如何在约束中使用ADL?
作为示例,我想使用约束来确保为模板参数isinf
实现函数T
。如果T
是float
,double
,long double
之一或整数类型,则可以通过以下方式完成:
#include <cmath>
template <typename T>
concept Test = requires (T a) {
std::isinf(a);
};
但是,我也想将此约束用于实现我自己的isinf
函数的自定义非标准数据类型。此功能未包含在std
名称空间中,因此我尝试了以下操作:
#include <cmath>
template <typename T>
concept Test = requires (T a) {
using std::isinf;
isinf(a);
};
这不起作用,因为require子句中的每个语句都应该是有效的要求,而using std::isinf
根本不是“要求”。
-
将
using std::isinf;
子句移至全局名称空间。但这将isinf
引入了全局命名空间,我想避免这种情况。 -
使用概念定义将
using std::isinf;
子句封装在名为ABC
的命名空间中,然后在命名空间之后直接添加using ABC::Test;
。这似乎有点不可思议。
有更好的解决方案吗?
解决方法
这种事情在Ranges中的工作方式是创建一个Customization Point Object。这紧密地反映了您的第二个选项(我们在自定义名称空间中粘贴了using-声明),除了我们还提供了一种机制,使用户可以调用正确的isinf
,而不必自己编写一堆相同的样板。 / p>
isinf
的自定义点对象看起来像这样:
namespace N {
// make our own namespace
namespace impl {
// ... where we can bring in std::isinf
using std::isinf;
struct isinf_t {
// our type is constrained on unqualified isinf working
// in a context where std::isinf can be found
template <typename T>
requires requires (T t) {
{ isinf(t) } -> std::same_as<bool>;
}
constexpr bool operator()(T t) const {
// ... and just invokes that (we know it's valid and bool at this point)
return isinf(t);
}
};
}
// we provide an object such that `isinf(x)` incorporates ADL itself
inline constexpr auto isinf = impl::isinf_t{};
}
现在我们有了一个对象,直接遵循一个概念:
template <typename T>
concept Test = requires (T t) {
N::isinf(t);
}
这正是range
概念的指定方式。
这应该有效。我对c ++ 20概念不太满意,所以不能保证语法正确。
namespace impl {
using std::isinf;
template<class T>
auto adl_isinf(T t) -> decltype(isinf(t));
// { return isinf(t); } // implementation not necessary depending on whether
// requires is an unevaluated context
}
template <typename T>
concept Test = requires (T a) {
impl::adl_isinf(a);
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。