如何编写使用 ADL 的概念
How to write concepts that make use of ADL
我想编写一个概念,使我能够验证使用 ADL 的给定语句是否有效并且具有正确的 return 类型。
在我的具体情况下,我想写一个 String
概念,它应该强制执行以下要求:
该类型的 const
和非 const
风格都有 begin
和 end
语义:
// Akin to what this function does for `T` and `T const`
template< typename T >
auto test(T& t) {
using std::begin;
return begin(t);
}
// calling test with `T` and `T const` should be valid.
begin
和end
的return类型对于const
和非const
口味都是一致的,它们满足std::contiguous_iterator
概念。
到目前为止,我使用了如下特征实现:
namespace Adl {
using std::begin;
template< typename T >
using HasBeginT = decltype(begin(std::declval< T >()));
}
template< typename T >
using HasBegin = std::experimental::is_detected< Adl::HasBeginT, T >;
但我想直接将此 ADL 用法嵌入到我的约束定义中。
习语 using std::X; X(...);
被认为是一个坏主意 post-C++20。现在的标准用法是为 X
创建一个 customization point object。或者在您的情况下,使用现有的自定义点对象:std::ranges::begin
.
您称呼此类自定义点的方式是将其完整拼写出来; 在内部,如果提供的类型有这样的调用,它可以进行 ADL 调用(没有 using
任何东西)。
我想编写一个概念,使我能够验证使用 ADL 的给定语句是否有效并且具有正确的 return 类型。
在我的具体情况下,我想写一个 String
概念,它应该强制执行以下要求:
该类型的
const
和非const
风格都有begin
和end
语义:// Akin to what this function does for `T` and `T const` template< typename T > auto test(T& t) { using std::begin; return begin(t); } // calling test with `T` and `T const` should be valid.
begin
和end
的return类型对于const
和非const
口味都是一致的,它们满足std::contiguous_iterator
概念。
到目前为止,我使用了如下特征实现:
namespace Adl {
using std::begin;
template< typename T >
using HasBeginT = decltype(begin(std::declval< T >()));
}
template< typename T >
using HasBegin = std::experimental::is_detected< Adl::HasBeginT, T >;
但我想直接将此 ADL 用法嵌入到我的约束定义中。
习语 using std::X; X(...);
被认为是一个坏主意 post-C++20。现在的标准用法是为 X
创建一个 customization point object。或者在您的情况下,使用现有的自定义点对象:std::ranges::begin
.
您称呼此类自定义点的方式是将其完整拼写出来; 在内部,如果提供的类型有这样的调用,它可以进行 ADL 调用(没有 using
任何东西)。