Может ли tr1::function проглотить возвращаемые значения?

Пункт 3 часто задаваемых вопросов boost:: function специально посвящен интересующему меня сценарию:

Почему есть обходные пути для пустых возвратов? C++ позволяет им! Пустые возвраты разрешены стандартом C++, как в следующем фрагменте кода:

void f();
void g() { return f(); }

Это допустимое использование boost:: function, потому что возврат void не используется. С пустыми возвратами мы попытались бы скомпилировать некорректный код, подобный следующему:

int f();
void g() { return f(); }

По сути, отсутствие использования возвращаемых значений void позволяет boost:: function проглотить возвращаемое значение. Это согласуется с тем, что пользователь может назначать и вызывать функции и функциональные объекты с параметрами, которые не совсем совпадают.

К сожалению, это не работает в VS2008:

int Foo();
std::tr1::function<void()> Bar = Foo;

Это приводит к ошибкам, начиная с:

c:\Program Files\Microsoft Visual Studio 9.0\VC\include\xxcallfun(7) : error C2562: 'std::tr1::_Callable_fun<_Ty>::_ApplyX' : 'void' function returning a value

Это сбой реализации VS2008 TR1? Это работает в VS2010? TR1 обращается к этой возможности? Как насчет C++0x?

1 ответ

Решение

Я считаю, что tr1 решает эту проблему. N1836 (последняя версия tr1) гласит:

Функциональный объект f типа F может вызываться для типов аргументов T1, T2, ..., TN и типа возврата R, если при заданных значениях t1, t2, ..., tNoftypesT1, T2, ..., TN соответственно INVOKE(f, t1, t2, ..., tN) корректно сформирован ([3.3]) и, если R не является пустым, конвертируется в R.

В вашем примере R является недействительным, и поэтому последняя часть требований для Callable (конвертируется в R) игнорируется.

Однако похоже, что C++0x (C++11) меняет правила. В С ++ 11 Callable определяется как INVOKE(f, t1, t2, ..., tN, R) который определен в [func.require] как требующий INVOKE(f, t1, t2, ..., tN) быть неявно конвертируемым в R, за исключением случаев, когда R является недействительным. Так что в C++ 11 ваш пример должен потерпеть неудачу.

Другие вопросы по тегам