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

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

Я пытаюсь сохранить указатель на функцию специализированного шаблона, а именно 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 Ответ

2 голосов
/ 21 января 2010

Аргументы шаблона 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), вы получите версию make_shared().

с 0 аргументами.
...