Общий лямбда-аргумент для std :: pair

Я пытаюсь понять, возможно ли это в общей лямбде C ++ 14, но я не могу найти правильный способ выразить это (или, возможно, это невозможно). Упрощенный пример:

auto confirmOperation = [](auto pr){
  assert(pr.second);
};

Идея в том, что если вы передадитеstd::pair гдеsecond этоbool (например, что возвращается изemplace функции), это можно посмотреть на это бул.

Если бы это был параметр шаблона, я мог бы явно показатьpair с типами пары как общие, но я не думаю, что это возможно с лямбда? Таким образом, вместо этого я отмечаю весь аргумент как универсальный, и, таким образом, компилятор, кажется, не в состоянии сделать вывод, что я передаю его как возвращение картыemplace().

Есть ли способ сделать это?

 Jonathan Mee10 июн. 2016 г., 15:17
Что ты здесь просишь?auto является универсальный тип, который может представлятьpair.Вы хотите изменить поведение функции по типам в возвращаемом?
 Smeeheey10 июн. 2016 г., 15:15
Можете ли вы показать окружающий код (т.е. с включенной картой emplace)?
 Yakk - Adam Nevraumont10 июн. 2016 г., 17:52
Таким образом, многие люди проголосовали за это. Если вы можете прочитать вышеизложенное и объяснить, что, по вашему мнению, говорит ОП, не могли бы вы перевести для меня?
 Oktalist10 июн. 2016 г., 19:41
В коде, который вы опубликовали, нет ничего плохого. Каким образом он не может удовлетворить то, что вам нужно?

Ответы на вопрос(3)

Решение Вопроса

Вы можете ограничить лямбду, используяenable_if:

auto confirmOperation = [](auto pr) ->
    std::enable_if_t<std::is_same<decltype(pr.second), bool>::value> {
  assert(pr.second);
};

пример.

 Jonathan Mee10 июн. 2016 г., 17:01
@ecatmur Да, именно поэтому я использовалdecltype(pr.second) по моему тоже;)
 Yakk - Adam Nevraumont10 июн. 2016 г., 17:27
В то время как опрятный, как это - ответ на "вопрос" OP? Короче говоря, почему вы думаете, что это то, что спрашивает ОП?
 Jonathan Mee10 июн. 2016 г., 17:38
@ Yakk Если у вас есть какие-то разъяснения о том, что хочет ОП, просим нас просветить (мой комментарий похоже, не справляется со своей работой.) В противном случае это такой же хороший ответ, как и любой другой. Это также было дано ОПпечать кунг-фу так что это что-то значит.
 johnbakers10 июн. 2016 г., 15:54
Вау, это какое-то кунг-фу.

Похоже, вы могли бы просто использоватьis_same а такжеstatic_assert Вот:

[](auto pr){
    static_assert(is_same_v<decltype(pr.second), bool>);
    assert(pr.second);
};

Или, если C ++ 17 не вариант, сообщениеstatic_assert требуется, и вы не сможете использоватьis_same_v:

[](auto pr){
    static_assert(is_same<decltype(pr.second), bool>::value, "ouch");
    assert(pr.second);
}

Живой пример

 KABoissonneault10 июн. 2016 г., 15:30
неstatic_assert без сообщения только C ++ 17? И что будет, еслиpr.second не является допустимым выражением?
 Jonathan Mee10 июн. 2016 г., 15:37
@ KABoissonneault Ты прав. Я написал живой пример, используя только C ++ 14. Еслиpr.second является недействительным, тоstatic_assert сработает. Что кажется, что мы хотели в первую очередь?

Вы можете определить функцию шаблона деталей реализации:

template<typename T>
void lambda_impl(std::pair<T, bool> const &p) {
  assert(p.second);
}

и затем назовите это в вашей лямбде как:

auto f = [](auto p) { lambda_impl(p); };

Следующая схема может быть доступна в будущем с появлением Concepts-Lite. Пока работает только на GCC:

auto f = [](std::pair<auto, auto> const &p) { assert(p.second); };

или даже лучше:

auto f = [](std::pair<auto, bool> const &p) { assert(p.second); };

P.S Clang правильно не компилировать из-за того, чтоauto параметры не являются частью C ++ 14.

 10101010 июн. 2016 г., 15:29
@NathanOliver В прошлый раз, когда я проверял, Херб сказал, что Concepts требует «больше работы», чтобы сделать это на C ++ 17
 KABoissonneault10 июн. 2016 г., 15:14
Это печально, потому что он компилируется наcoliru.stacked-crooked.com/a/288f843d3219dc07, Это стандарт или расширение GCC?
 NathanOliver10 июн. 2016 г., 15:27
@ 101010 Это будет в C ++ 1z?
 KABoissonneault10 июн. 2016 г., 15:19
Из cppreference: «Если auto используется в качестве типа параметра, лямбда является общей лямбда». посколькуauto это не тип параметра, то это не может быть общая лямбда. Я думаю, что это отличная особенность, хотя.
 Smeeheey10 июн. 2016 г., 15:12
Это не компилируется в clang с включенным c ++ 14
 KABoissonneault10 июн. 2016 г., 15:27
@NathanOliver Посмотрите на Concepts TS, который, к сожалению, не является частью C ++ 17
 NathanOliver10 июн. 2016 г., 15:17
Также не работает MSVS2015 (я не знаю, действительно хороший инструмент для проверки на соответствие).
 Nicol Bolas10 июн. 2016 г., 15:24
@ 101010: Ваше «даже лучше» действительно только с Concepts TS.
 NathanOliver10 июн. 2016 г., 15:29
Облом. Спасибо за информацию, ребята
 Jonathan Mee10 июн. 2016 г., 15:46
@ KABoissonneault Я думал, что Херб Саттер говорил, чтоесли комитет по стандартам позволитstatic_if мы могли бы иметь Концепции с C ++ 17или комитет по стандартам официально отказался от этого?
 10101010 июн. 2016 г., 15:26
@NicolBolas Извините всех, я исправил, что я работаю с GCC, и я забыл, что автоматические параметры будут доступны в будущем :)
 johnbakers10 июн. 2016 г., 15:15
Я могу только предположить, что это нестандартное поведение?
 johnbakers10 июн. 2016 г., 15:12
очень красиво, но мой Clang с -std = c ++ 14 не скомпилирует это. это говорит:'auto' not allowed in template argument и это подчеркивает первоеauto вpair у тебя есть

Ваш ответ на вопрос