Может ли tr1 :: function проглотить возвращаемые значения? - PullRequest
9 голосов
/ 08 июля 2011

Функция Boost :: function FAQ 3 специально описывает интересующий меня сценарий:

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

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

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

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

По сути, не использовать пустые возвраты позволяет 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 Ответ

8 голосов
/ 08 июля 2011

Я думаю, что 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) меняет правила.В C ++ 11 Callable определяется как INVOKE(f, t1, t2, ..., tN, R), который определен в [func.require] как требование, чтобы INVOKE(f, t1, t2, ..., tN) был неявно конвертируемым в R, за исключением случаев, когда R является недействительным.Таким образом, в C ++ 11 ваш пример должен потерпеть неудачу.

...