Search code examples
c++c++11decltypeargument-dependent-lookupusing-declaration

Using namespace inside decltype


I have a function that looks more or less like this:

template<class C> auto f(C const& c) -> decltype(begin(c)){
    using std::begin;
    return begin(c);
}
  1. The body of the function exploits the "using and use" idiom and

  2. thanks to the decltype, will SFINAE if the return type is not valid.

However it is not perfect in general because I have no way to tell the decltype to have a using std declaration for begin.

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

would also be inconsistent, e.g. when decltype(c) and begin belongs to a different namespace.

Is there way around it?

Ideally, I want something like

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

I think a lambda could work in principle

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

but lambdas are forbidden inside decltype.


In GCC there is an interesting language extension ("expression statements") that is promising, however it doesn't work outside the body of the function (same as lambdas are not allowed in unevaluated context). Otherwise it would be a solution.

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...
}

Solution

  • You can delegate to an ADL enabled namespace

    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);
    }