Ошибка привязки make_unique
У меня проблемы с использованием std::bind
с std::make_unique
,
У меня есть объект, в конструктор которого я передаю фабричные функции для создания std::unique_ptr
с объектов другого типа класса.
Используя VS2013, это работает:
Tester tester(
[](){return std::make_unique<AlphaBetaSingleThreadSSE>( 0,7 ); },
[](){return std::make_unique<AlphaBetaSingleThread>( 0,7 ); },
20 );
Это дает мне ошибки компиляции:
Tester tester(
std::bind( std::make_unique<AlphaBetaSingleThreadSSE>,0,7 ),
std::bind( std::make_unique<AlphaBetaSingleThread>,0,7 ),
20 );
Состояние сообщений об ошибках:
ошибка C2512: "AlphaBetaSingleThread": не доступен соответствующий конструктор по умолчанию
ошибка C2512: "AlphaBetaSingleThreadSSE": не доступен соответствующий конструктор по умолчанию
Почему std::bind
сбой подхода?
1 ответ
std::make_unique
определяется следующим образом:
§ 20.8.1.4 [unique.ptr.create]
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
1 Примечание: эта функция не должна участвовать в разрешении перегрузки, если только
T
это не массив.2 Возвращает:
unique_ptr<T>(new T(std::forward<Args>(args)...)).
Путем явного создания экземпляра этого шаблона функции с std::make_unique<AlphaBetaSingleThreadSSE>
Вы получаете следующую специализацию:
std::unique_ptr<AlphaBetaSingleThreadSSE> make_unique()
{
return std::unique_ptr<AlphaBetaSingleThreadSSE>(new AlphaBetaSingleThreadSSE());
}
То есть он больше не позволит передавать дополнительные аргументы, которые будут перенаправлены в конструктор AlphaBetaSingleThreadSSE
и вместо этого попытается использовать конструктор по умолчанию AlphaBetaSingleThreadSSE
(который не существует, как говорится в сообщении об ошибке).
Вы можете обойти это, указав также параметр типа шаблона Args
:
std::make_unique<AlphaBetaSingleThreadSSE, const int&, const int&>
но тогда вам не удастся извлечь выгоду из совершенной пересылки, и это не переносимое решение в любом случае. Лучшее решение - остаться с лямбдой.