Рассмотрим C++ 11 код:Требует ли C++ 11, чтобы этот лямбда был объявлен изменчивым?
#include <functional>
#include <cstdlib>
template <typename F>
void test(F &&f) {
auto foo = [f]() {
f();
};
foo();
}
int main() {
test(std::bind(std::puts, "hello"));
return 0;
}
GCC и Clang принять это, как действительный C++ 11 кода, но Visual Studio 2013 требует лямбда быть объявлены изменяемыми (auto foo = [f]() mutable { ... }
). В противном случае я получаю эту ошибку:
error C3848: expression having type '
const std::_Bind<true,int,int (__cdecl *const)(const char *),const char (&)[6]>
' would lose some const-volatile qualifiers in order to call 'int std::_Bind<true,int,int (__cdecl *const)(const char *),const char (&)[6]>::operator()<>(void)
'
Является ли Visual Studio правом отклонить этот код без изменчивости, или это действительно C++ 11?
(Любопытно Clang отвергает код, если вы измените std::bind(std::puts, "hello")
на std::bind(std::exit, 0)
, по-видимому, потому что он считает noreturn
сделать тип функции различны;. Я совершенно уверен, что это ошибка)
Нет, это не соответствует стандарту. «Эффект' g (u1, u2, ..., uM) 'должен быть' INVOKE (fd, v1, v2, ..., vN, result_of :: type) '" означает, что результат 'bind' должен быть вызван, если объект связанной функции. Указатель функции может быть вызван независимо от того, является ли он 'const', поэтому обязательная вещь' bind' тоже должна быть. –
@MikeSeymour 'g' - это возвращаемое значение' std :: bind', и указано только поведение 'g (...)'. Где стандарт требует поддержки вызовов с помощью ссылки на const, соответствующей этому возвращаемому значению? – hvd
В приведенной выше цитате (20.8.9.1.2/3) плюс следующее предложение «где' cv' представляет cv-квалификаторы 'g'. Вызов 'g' имеет тот же эффект, что и вызов' fd' (объект связанной функции) с cv-квалификаторами 'g', примененными к' fd'; поэтому вызов соответствующей 'const' -копии/ссылки' g' должен быть действительным, если вызывается вызов 'const FD'. Здесь «FD» - это тип указателя функции, который является вызываемым независимо от того, является ли он 'const'. –