Рассмотрим этот код С++ 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 принимают это как действительный код С++ 11, но Visual Studio 2013 требует, чтобы лямбда была объявлена изменчивой (auto foo = [f]() mutable { ... }
). В противном случае я получаю эту ошибку:
ошибка C3848: выражение, имеющее тип '
const std::_Bind<true,int,int (__cdecl *const )(const char *),const char (&)[6]>
', потеряло бы некоторые константно-летные квалификаторы, чтобы вызвать 'int std::_Bind<true,int,int (__cdecl *const )(const char *),const char (&)[6]>::operator ()<>(void)
'
Является ли Visual Studio правом отклонять этот код без изменчивости, или это действительно С++ 11?
(Любопытно, что Clang отклоняет код, если вы меняете std::bind(std::puts, "hello")
на std::bind(std::exit, 0)
, по-видимому, потому, что он считает, что noreturn
делает тип функции другим, я совершенно уверен, что это ошибка.)