首页 > 解决方案 > 在 decltype 中使用命名空间

问题描述

我有一个看起来或多或少像这样的函数:

template<class C> auto f(C const& c) -> decltype(begin(c)){
    using std::begin;
    return begin(c);
}
  1. 函数体利用“ usingand use”习语和

  2. 感谢decltype, 如果返回类型无效,将 SFINAE。

decltype但是,一般来说它并不完美,因为我无法using std告诉begin.

template<class C> auto f(C const& c) -> decltype(std::begin(c))

也会不一致,例如何时decltype(c)begin属于不同的命名空间。

有办法解决吗?

理想情况下,我想要类似的东西

template<class C> auto f(C const& c) -> decltype(using std::begin; begin(c))

我认为 lambda 原则上可以工作

template<class C> auto f(C const& c) -> decltype([&]{using std::begin; return begin(c)})

但内部禁止使用 lambda decltype


在 GCC 中,有一个有趣的语言扩展(“表达式语句”)很有前途,但是它在函数体之外不起作用(与未评估的上下文中不允许使用 lambda 相同)。 否则这将是一个解决方案。

template<class C> auto g(C const& c) 
->decltype(({using std::begin; begin(c);})){ // ...that doesn't work here
    return(({using std::begin; begin(c);})); // gcc extesion...
}

标签: c++c++11decltypeargument-dependent-lookupusing-declaration

解决方案


您可以委托给启用 ADL 的命名空间

namespace detail
{
    using std::begin;
    template<class C> auto f(C const& c) -> decltype(begin(c)){
        return begin(c);
    }
}

template<class C> auto f(C const& c) -> decltype(detail::f(c)){
    return detail::f(c);
}

推荐阅读