перегрузка c ++: строковый литерал против boost :: function неоднозначность - PullRequest
5 голосов
/ 21 января 2011

код моей проблемы:

#include <string>
#include <boost/function.hpp>

void func (const std::string&) {}
void func (const boost::function<void()>&) {}

int main() {
    func (main); // good
    func ("bad");
    return 0;
}

=>

error: call of overloaded ‘func(const char [4])’ is ambiguous
overload.cpp:4: note: candidates are: void func(const std::string&)
overload.cpp:5: note:                 void func(const boost::function<void ()()>&)

Я знаю, что мог бы решить эту проблему, явно вызвав func (string ("bad")); или предоставляя func (const char *), но мне интересно, есть ли способ сохранить сторону вызывающей стороны, как в примере, и не вводить больше перегрузок.

Может быть, что-то с boost :: enable_if? Спасибо за любые подсказки.

Ответы [ 2 ]

4 голосов
/ 21 января 2011

Вы не можете легко решить это.boost::function<> и std::function<> поддерживают не только функторы, вызываемые f(), но и указатели на члены, вызываемые (secondArg.*firstArg)() и члены данных, поэтому их конструкторы в основном отбрасывают все, а затем решают, что делать с типом,

Совсем нетривиально написать такой класс тестирования SFINAE, который защищает от неявных преобразований (и я даже не уверен, будет ли это вообще возможно, поскольку стандартная библиотека этого не делает.должна быть какая-то причина).Помните, что тип может вызываться из-за множества различных свойств - у него может быть функция преобразования в тип указателя функции и т. Д. Написание класса SFINAE, который может сделать эту работу, означает отклонение неявного преобразования в некоторых случаях и принятие неявного преобразования вдругие случаи основаны на действительно не очевидных свойствах вообще.

Если вы хотите избежать этой неоднозначности, я бы попробовал просто выбрать другое имя функции или, если это проблема с одним выстрелом, выполнить приведение на стороне вызывающего.

0 голосов
/ 21 января 2011

добавить это:

void func (const char *s) {  func(string(s)); }

обновление

template<class A0, ...>
void func (const A0 &a0, ...) {
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...