Неоднозначная перегрузка доступа к шаблонным функциям без аргументов с переменными параметрами

Да, название может напугать детей, но на самом деле это довольно просто.

Я пытаюсь сохранить указатель на функцию специализированного шаблона, а именно boost::make_shared (boost 1.41), как показано на рисунке:

boost::shared_ptr<int> (*pt2Function)() = boost::make_shared<int>;

Однако он не будет компилироваться (GCC 4.4.1) из-за того, что boost:: make_shared имеет следующие две специализации, которые компилятор не может отличить в этом контексте:

template< class T > boost::shared_ptr< T > make_shared()
...
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )

Ошибка, для справки:

In function ‘int main()’:
error: converting overloaded function ‘make_shared’ to type ‘class boost::shared_ptr<int> (*)()’ is ambiguous
boost/smart_ptr/make_shared.hpp:100: error: candidates are: boost::shared_ptr<X> boost::make_shared() [with T = int]
boost/smart_ptr/make_shared.hpp:138: error:                 boost::shared_ptr<X> boost::make_shared(Args&& ...) [with T = int, Args = ]

Если я закомментирую не вариационную вариацию, код компилируется нормально.

Кто-нибудь знает правильный синтаксис для разрешения неоднозначности между двумя функциями без аргументов, как это?

1 ответ

Решение

Аргументы шаблона Variadic означают, что вы берете 0 ..n аргументов шаблона, поэтому обе ваши версии совпадают.
Вы можете устранить неоднозначность, добавив другой параметр шаблона ко второй версии, чтобы он принимал аргументы 1..n.
Примерно так должно работать:

template< class T, class Arg1, class... Args > 
boost::shared_ptr< T > make_shared(Arg1&& arg1, Args && ... args )

Но, как правильно указал UncleBens, вам даже не нужны две версии. В вашем случае должно быть достаточно:

template< class T, class... Args > 
boost::shared_ptr<T> make_shared(Args && ... args );

Если вы используете только один аргумент шаблона (т.е. T), вы получаете версию с 0 аргументами make_shared(),

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