Может ли noexcept
модификатор применить к лямбда-выражению? Если так, то как?
Можно noexcept
сделать ограничение на аргумент функции? Например, что-то вроде в следующем коде, где означает, что функция обратного вызова должна быть noexcept
?
//probably not valid code - I'm just trying to express the idea
void f_async(std::function<void (int) noexcept> callback) noexcept
{
...
}
Это может почти это можно сделать с помощью следующего кода, но мне интересно, есть ли способ использовать что-то вроде вышеупомянутой альтернативы.
void f_async(std::function<void (int)> callback)
noexcept(callback(std::declval<int>()))
{
...
}
Проблема здесь, конечно, в том, что f_async
может быть noexcept(false)
если обратный вызов noexcept(false)
— Я хочу сделать более сильное заявление, что f_async
является всегда noexcept
Это означает, что он вызывается только если вы используете noexcept
Перезвоните.
Может ли
noexcept
модификатор применить к лямбда-выражению? Если так, то как?
добавлять noexcept
после скобок:
[](Args args) noexcept { ... }
Можно
noexcept
сделать ограничение на аргумент функции?
Да, используйте enable_if:
template <typename F>
auto f_async(const F& func) noexcept
-> typename std::enable_if<noexcept(func(0))>::type {
func(0);
}
int main() {
f_async([](int x) noexcept {});
f_async([](int x) {}); // <- this line won't compile
}
тем не мение, этот метод не может работать напрямую в g ++ 4.7 (он работает в clang ++ 3.2), потому что он не может искажать noexcept
выражение еще:
3.cpp: 5: 6: извините, не реализовано: искажение noexcept_expr
Вы можете обойти это, используя структуру оболочки:
template <typename F, typename... Args>
struct EnableIfNoexcept
: std::enable_if<noexcept(std::declval<F>()(std::declval<Args>()...))> {};
template <typename F>
auto f_async(const F& func) noexcept -> typename EnableIfNoexcept<F, int>::type {
func(0);
}
По первому вопросу:
Может ли модификатор noexcept быть применен к лямбда-выражению? Если так, то как?
Да, просто добавьте спецификацию исключения после списка параметров:
[] (int i) noexcept { return i * 1; };
// ^^^^^^^^
В соответствии с пунктом 5.1.2 / 5 стандарта C ++ 11:
Тип закрытия для лямбда-выражения имеет открытый оператор вызова встроенной функции (13.5.4), параметры которого
и тип возврата описываются параметром-объявлением-лямбда-выражения и трейлинг-возвращением
тип соответственно. Этот оператор вызова функции объявляется const (9.3.1) тогда и только тогда, когда лямбда-выражение
Параметр-объявление-предложение не сопровождается изменяемым. Он не является ни виртуальным, ни объявленным
неустойчивый. Аргументы по умолчанию (8.3.6) не должны указываться в условии объявления параметров лямбда-декларатора.
Любая спецификация исключения, указанная в лямбда-выражении, применяется к соответствующей функции
оператор вызова. Атрибут-спецификатор-seq в лямбда-деклараторе относится к типу соответствующего
оператор вызова функции. [Примечание: имена, на которые ссылается лямбда-декларатор, ищутся в контексте
который появляется лямбда-выражение. —Конечная записка]