Выделение лямбда-выражения в вызове функции шаблона C ++ [дубликат]

Один подход, который работает практически из любого места, в том числе из мест, где у вас нет Activity или View, заключается в том, чтобы захватить Handler в основной поток и показать тост:

public void toast(final Context context, final String text) {
  Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
    public void run() {
      Toast.makeText(context, text, Toast.DURATION_LONG).show();
    }
  });
}

Преимуществом этого подхода является то, что он работает с любыми Context, включая Service и Application.

4
задан Mithrandir 2 August 2012 в 14:51
поделиться

2 ответа

Стефан Т. Лававей объясняет, почему это не работает в этом видео . В основном проблема заключается в том, что компилятор пытается вывести BaseT из как параметр std::vector , так и std::function. Лямбдой в C ++ является , а не типа std::function, это неназванный, уникальный неединичный тип, который можно конвертировать в указатель функции, если у него нет списка захвата (empty []) , С другой стороны, объект std::function может быть создан из любого возможного типа вызываемого объекта (указатели функций, указатели функций-функций, объекты функций).

Обратите внимание, что я лично не понимаю, почему вы хотите ограничить входящие функторы этой специфической сигнатурой (в дополнение к тому факту, что косвенность через оболочку полиморфной функции, например std::function, намного более неэффективна, чем прямой вызов функтора (который может даже быть встроенным)), но вот рабочая версия. В принципе, он отключает дедукцию аргумента на части std::function и выводит BaseT из аргумента std::vector:

template<class T>
struct Identity{
  typedef T type;
};

template<typename BaseT>
vector<BaseT> findMatches(vector<BaseT> search, 
    typename Identity<function<bool (const BaseT &)>>::type func)
{
    vector<BaseT> tmp;

    for(auto item : search)
    {
        if( func(item) )
        {
            tmp.push_back(item);
        }
    }

    return tmp;
}

Пример Live на Ideone.

Другим возможным способом было бы не ограничивать тип функтора напрямую, а косвенно через SFINAE:

template<class T, class F>
auto f(std::vector<T> v, F fun)
    -> decltype(bool(fun(v[0])), void())
{
  // ...
}

Пример Live на Ideone.

Эта функция будет удалена из набора перегрузки, если fun не принимает аргумент типа T& или если тип возврата не конвертируется в bool. , void() делает тип возврата f void.

9
ответ дан Xeo 5 September 2018 в 06:50
поделиться

Как было показано другими плакатами, это вычет аргумента шаблона для std :: function.

Один интуитивно понятный способ сделать второй фрагмент кода - добавить базовый тип при вызове шаблона функция: findMatches<int>.

Другой способ, не упомянутый Xeo, используется std :: is_convertible:

template<typename BaseT, typename FUNC>
vector<BaseT> findMatches(vector<BaseT> search, function <bool (const BaseT &)> func)
{
    static_assert(std::is_convertible<FUNC, function<bool (const BaseT &)> >::value, "func must be convertible to ...");

    vector<BaseT> tmp;

    for(auto item : search)
    {
        if( func(item) )
        {
            tmp.push_back(item);
        }
    }

    return tmp;
}

Он избегает обертывания lamda в std :: function и обеспечивает сообщение об ошибке.

0
ответ дан youwei 5 September 2018 в 06:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: