Использование пространства имен внутри decltype - PullRequest
0 голосов
/ 21 мая 2018

У меня есть функция, которая выглядит примерно так:

template<class C> auto f(C const& c) -> decltype(begin(c)){
    using std::begin;
    return begin(c);
}
  1. В теле функции используется идиома "using и использование" и

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

Я думаю, что лямбда может работать в принципе

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

, но лямбды запрещены внутри decltype.


В GCC есть многообещающее расширение языка («операторы выражений»), которое является многообещающим, однако оно не работает вне тела функции(так же, как лямбды не допускаются в неоцененном контексте). В противном случае это будет решение.

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

1 Ответ

0 голосов
/ 22 мая 2018

Вы можете делегировать в пространство имен с поддержкой 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);
}
...