将 using 语句应用于函数的 return 类型,而不应用于整个命名空间
Apply using statement to the return type of a function without applying to the entire namespace
我正在尝试创建一个接受底层容器的函数,并且 return 是一个 boost::iterator_range 基于对元素进行一些处理的自定义迭代器。
例如
// The range class, templated on the underlying iterator type
template<class Iter> using CustomRange = boost::iterator_range<CustomIterator<Iter>>;
using std::begin;
template <class Container>
auto make_custom_range(Container& c) -> CustomRange<decltype(begin(c))> {
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}
代码有效(为 CustomIterator 和 make_custom_range_from_iterators 提供了合适的定义)。
我担心的是 using std::begin
声明,我认为这会导致 std::begin 被导入到声明我的函数的整个名称空间中。我不想在 decltype 中显式使用 std::begin 以便 ADL 可以工作(如在这个问题中:Relying on ADL for std::begin() and std::end()?)。
我认为在 C++14 中,我可以在这里使用自动 return 类型。有 C++11 解决方案吗?有没有办法让 return 类型看到 using 声明而不将其暴露给整个命名空间?
将 using 声明放在单独的命名空间中:
namespace adl_helper
{
using std::begin;
template <typename T>
auto adl_begin(T&& t) -> decltype(begin(std::forward<T>(t)));
}
template <class Container>
auto make_custom_range(Container& c)
-> CustomRange<decltype(adl_helper::adl_begin(c))>
// ~~~~~~~~~~~~~~~~~~~~^
{
using std::begin;
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}
将所有内容都放入另一个命名空间并将您的 using
放在那里。然后将您的新助手带入您的顶级命名空间:
namespace details {
using std::begin;
using std::end;
template <typename C>
auto adl_begin(C&& c) -> decltype(begin(std::forward<C>(c))) {
return begin(std::forward<C>(c));
}
template <typename C>
auto adl_end(C&& c) -> decltype(end(std::forward<C>(c))) {
return end(std::forward<C>(c));
}
}
using details::adl_begin;
using details::adl_end;
template <typename C>
using adl_begin_t = decltype(adl_begin(std::declval<C>()));
template <typename C>
using adl_end_t = decltype(adl_end(std::declval<C>()));
在 C++14 中,您不需要尾随的 return 类型,但也需要对 cbegin
和 cend
执行相同的操作。这样,您就不必再记住 using
s,只需在任何地方使用 adl_*
方法即可:
template <class Container>
CustomRange<adl_begin_t<Container&>> make_custom_range(Container& c) {
return make_custom_range_from_iterators(adl_begin(c), adl_end(c));
}
我正在尝试创建一个接受底层容器的函数,并且 return 是一个 boost::iterator_range 基于对元素进行一些处理的自定义迭代器。
例如
// The range class, templated on the underlying iterator type
template<class Iter> using CustomRange = boost::iterator_range<CustomIterator<Iter>>;
using std::begin;
template <class Container>
auto make_custom_range(Container& c) -> CustomRange<decltype(begin(c))> {
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}
代码有效(为 CustomIterator 和 make_custom_range_from_iterators 提供了合适的定义)。
我担心的是 using std::begin
声明,我认为这会导致 std::begin 被导入到声明我的函数的整个名称空间中。我不想在 decltype 中显式使用 std::begin 以便 ADL 可以工作(如在这个问题中:Relying on ADL for std::begin() and std::end()?)。
我认为在 C++14 中,我可以在这里使用自动 return 类型。有 C++11 解决方案吗?有没有办法让 return 类型看到 using 声明而不将其暴露给整个命名空间?
将 using 声明放在单独的命名空间中:
namespace adl_helper
{
using std::begin;
template <typename T>
auto adl_begin(T&& t) -> decltype(begin(std::forward<T>(t)));
}
template <class Container>
auto make_custom_range(Container& c)
-> CustomRange<decltype(adl_helper::adl_begin(c))>
// ~~~~~~~~~~~~~~~~~~~~^
{
using std::begin;
using std::end;
return make_custom_range_from_iterators(begin(c),end(c));
}
将所有内容都放入另一个命名空间并将您的 using
放在那里。然后将您的新助手带入您的顶级命名空间:
namespace details {
using std::begin;
using std::end;
template <typename C>
auto adl_begin(C&& c) -> decltype(begin(std::forward<C>(c))) {
return begin(std::forward<C>(c));
}
template <typename C>
auto adl_end(C&& c) -> decltype(end(std::forward<C>(c))) {
return end(std::forward<C>(c));
}
}
using details::adl_begin;
using details::adl_end;
template <typename C>
using adl_begin_t = decltype(adl_begin(std::declval<C>()));
template <typename C>
using adl_end_t = decltype(adl_end(std::declval<C>()));
在 C++14 中,您不需要尾随的 return 类型,但也需要对 cbegin
和 cend
执行相同的操作。这样,您就不必再记住 using
s,只需在任何地方使用 adl_*
方法即可:
template <class Container>
CustomRange<adl_begin_t<Container&>> make_custom_range(Container& c) {
return make_custom_range_from_iterators(adl_begin(c), adl_end(c));
}