У меня есть этот код:
#include <iostream>
#include <functional>
struct A
{
int operator()(int i) const {
std::cout << "F: " << i << std::endl;
return i + 1;
}
};
int main()
{
A a;
std::tr1::function<int(int)> f = std::tr1::ref(a);
std::cout << f(6) << std::endl;
}
Цель состоит в том, чтобы передать объект функтора reference_wrapper, способом для предотвращения бесполезной копии costructor вызовы. Я ожидаю следующий вывод:
F: 6
7
Это работает правильно с GCC> = 4.4.0, Visual Studio 2008 и с повышением путем замены станд.:: пространство имен tr1 с повышением. Это только не работает с новой Visual Studio 2010 и Бета 2 Экспресса и Предвыпускная версия.
Этот новый C++ функции прослушивается в vs2010? Или существует некоторая ошибка или неправильное употребление в коде?
Думаю, я нашел причину. Это то, что TR1 3.4 / 2
говорит о result_of
, используемом при определении типа возвращаемого значения reference_wrapper
:
Реализация может определять член типа любым способом, который производит точный тип выражения f (t1, t2, ..., tN) для данные типы. [Примечание: намерение состоит в том, что реализациям разрешено использовать специальные перехватчики компилятора - конец примечания]
И затем параграф 3:
Если F не является функциональным объектом, определенным стандартной библиотекой, и если любая из реализаций не может определить тип выражения f (t1, t2, ..., tN) или, если выражение неправильно сформировано, реализация должна использовать следующий процесс для определения члена типа:
- Если F, возможно, квалифицируется cv тип класса без члена с именем
тип_результатов
или еслиимя_типа F :: тип_результатов
не является типом:
- Если N = 0 (нет аргументы), тип недействителен.
- Если N> 0, типом является
typename F :: template result
:: type
Сообщение об ошибке является артефактом попытки выполнить эти ошибки. спины. Предоставьте typedef для result_type
в int
, и я думаю, он должен работать. Обратите внимание, что в C ++ 0x
все по-другому.Он не полагается на шаблон result_type
или result
, поскольку может использовать decltype
.
Если с
он не работает с MSVC10 в режиме C ++ 0x, я бы сказал, что это пахнет ошибкой. Но, может быть, кто-то еще знает, что происходит. Он может (но не гарантируется) работать с
в режиме C ++ 0x, если этот заголовок выбирает способ decltype
вместо :: результат_типа
. Я бы набрал result_type
- таким образом, я думаю, он должен работать всегда, независимо от того, используется ли заголовок tr1
или заголовок c ++ 0x
.
Также обратите внимание, что boost :: tr1
говорит в своей документации, что он не поддерживает оператор вызова функции (но он просто поддерживает неявные преобразования в T &
).
Я столкнулся с аналогичной проблемой здесь: Предотвращение ненужных копий объектов функтора C ++
Чтобы заставить его скомпилировать на MSVC10, Мне пришлось получить свой объект функции из std :: unary_function.