Kan*_* Li 7 c++ c++11 c++14 c++17
有没有办法将模式包装成一般的模板函数?
template <typename C>
auto Begin(C&& c) -> ??? {
using std::begin;
return begin(std::forward<C>(c));
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是如何在这里编写函数的返回类型?
我想要这个的原因是我想写一个模板变量
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;
Run Code Online (Sandbox Code Playgroud)
这里的问题是std::begin不会发现的定制化重载begin为C通过ADL.如果有人为此做了解决方法,也欢迎.
您需要将其包装在另一个名称空间中,即:
namespace details {
using std::begin;
template <typename C>
auto Begin(C&& c) -> decltype(begin(std::forward<C>(c)))
{
return begin(std::forward<C>(c));
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
template <typename C>
constexpr bool IsBidirectionalContainer =
std::is_base_of<std::bidirectional_iterator_tag,
typename std::iterator_traits<
decltype(details::Begin(std::declval<C>()))>::iterator_category>::value;
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你拒绝Begin在命名空间内定义,你可以使用类型别名来绕过它.
namespace details {
using std::begin;
template <typename C>
using type = decltype(begin(std::forward<C>(c)));
}
template <typename C>
auto Begin(C&& c) -> details::type<C>
{
return begin(std::forward<C>(c));
}
Run Code Online (Sandbox Code Playgroud)
虽然这可能比必要的工作更多.前瞻声明可能就足够了.
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |