【发布时间】:2017-12-30 00:19:46
【问题描述】:
有没有办法将模式包装成一个通用的模板函数?
template <typename C>
auto Begin(C&& c) -> ??? {
using std::begin;
return begin(std::forward<C>(c));
}
这里的问题是这里函数的返回类型怎么写?
我想要这个的原因是我想写一个模板变量
template <typename C>
constexpr bool IsBidirectionalContainer =
std::is_base_of<std::bidirectional_iterator_tag,
typename std::iterator_traits<
decltype(std::begin(std::declval<C>()))>::iterator_category>::value;
这里的问题是 std::begin 不会通过 ADL 为 C 找到 begin 的自定义重载。如果有人对此有解决方法,也欢迎。
【问题讨论】:
-
我忘记是 C++14 还是 C++17,但至少对于 C++17,在这种情况下您不必声明返回类型。编译器会帮你解决的。否则,只需使用
decltype。 -
@NirFriedman,不,不完全相同。它使用 ADL。请参阅en.cppreference.com/w/cpp/iterator/begin中的“用户定义的重载”
-
是的,抱歉误会了。不过,重载免费开始功能有点奇怪/不习惯;它应该作为一个成员来实现。
-
@SamVarshavchik,对于 C++14,该怎么做? decltype 只接受一个表达式,所以你不能同时拥有
using std::begin;和begin(c) -
@MárioFeroldi 除非您的容器不在
std::中,然后 ADL 不会。或者你的容器是一个原始数组。