2012-04-10 1 views
14

Я использую бета-версию Visual Studio 11, и мне любопытно ошибка компиляции. Я хочу сохранить объект std :: function в своем классе.C++ 11 std :: function ограничивает количество аргументов, которые может иметь указатель функций?

typedef std::function<void (int, const char*, int, int, const char*)> MyCallback; 

В моем классе у меня есть,

MyCallback m_callback; 

Это компилируется нормально. Если я добавлю еще один аргумент в список, он терпит неудачу.

typedef std::function<void (int, const char*, int, int, const char*, int)> MyCallback; 

Неудача:

>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(535): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>' 
1>   with 
1>   [ 
1>    _Tx=void (int,const char *,int,int,const char *,int) 
1>   ] 
1>   f:\development\projects\applications\my.h(72) : see reference to class template instantiation 'std::function<_Fty>' being compiled 
1>   with 
1>   [ 
1>    _Fty=void (int,const char *,int,int,const char *,int) 
1>   ] 
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(536): error C2504: 'type' : base class undefined 
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>' 
1>   with 
1>   [ 
1>    _Tx=void (int,const char *,int,int,const char *,int) 
1>   ] 
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C2146: syntax error : missing ';' before identifier '_Mybase' 
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 

Это динамически подключаемая библиотека, которая подготавливает данные для передачи в другое приложение. Я могу, конечно, переработать формат данных, чтобы его можно было передавать с меньшим количеством аргументов, но мне было интересно, почему я вижу этот предел?

Переключение обратно в указатель на функцию с стиле,

typedef void (*MyCallback)(int, const char*, int, int, const char*, int); 

, кажется, работает хорошо.

ответ

37

Этот предел устанавливается реализацией в Visual Studio.

Спецификация C++ для std::function не устанавливает никаких ограничений. std::function использует вариационные шаблоны для работы с любым количеством аргументов. Реализации могут иметь ограничение, основанное на, например, ограничениях на вложение экземпляров шаблона, но оно должно быть большим. Спецификация предлагает 1024 как хорошую минимальную поддерживаемую глубину вложенности, а 256 - как хороший минимум для аргументов, разрешенных в одном вызове функции, например.

Visual Studio (с VS11) не имеет вариационных шаблонов. Они имитируют до 5 аргументов в VS11, хотя вы можете изменить его до 10. Сделайте это, указав в своем проекте _VARIADIC_MAX. Это может значительно увеличить время компиляции.

Обновление: VS 2012 Nov CTP добавляет поддержку вариативных шаблонов, но стандартная библиотека еще не обновлена, чтобы использовать их. После его обновления вы сможете использовать столько аргументов, сколько хотите, с помощью std::function.

+1

Правильный ответ. Также см. [Magic && Secrets] (http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/STL11-Magic-Secrets) самим STL в GoingNative 2012, он упоминает об этом один или два раза. – Xeo

+0

Интересная вещь. Я помню, что внедрение вариативных шаблонов было лишь незначительным усилием на стороне g ++. –

+0

Отлично, что отвечает на мой вопрос, спасибо! – BZor