2011-01-21 14 views
5

mój kod Problem:C++ przeciążenie: string literal vs. boost :: function dwuznaczności

#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()()>&) 

wiem mogę rozwiązać ten problem przez jawne wywołanie func (ciąg ("zły ")); lub przez zapewnienie func (const char *), ale zastanawiam się, czy istnieje sposób na zachowanie strony wywołującej, jak w przykładzie i bez wprowadzania większej liczby przeciążeń.

Może coś z doładowaniem :: enable_if? Dzięki za wszelkie wskazówki.

+0

Czy naprawdę sądzisz, że przyczyną jest przeciążenie, które ma funkcję 'boost :: function', czy próbowałeś na przykład skompilować bez tego przeciążenia? Czy to będzie działało? – Nim

+1

tak jest spowodowane przez funkcję boost :: function. Zamieszczony przeze mnie przykład odtwarza całą sytuację. – denis

+0

yeah - nie testowałem przed pytaniem, tylko trochę oszołomiony, że tak było - wygląda na to, że jest .. hmm .. na krótko od zapewnienia przeciążenia dla wszystkiego, nie jestem pewien, czy jest na to porządne rozwiązanie ... – Nim

Odpowiedz

4

nie można łatwo rozwiązać ten problem. boost::function<> i std::function<> nie obsługują tylko funktorów wywoływanych przez f(), ale także wskaźnika dla członków wymuszanych przez (secondArg.*firstArg)() i elementów danych, więc ich konstruktorzy w zasadzie wszystko sypią, a później decydują, co zrobić z typem.

Nie jest wcale banalnie napisać taką klasę testową SFINAE, która chroni przed niejawnymi konwersjami (i nie jestem nawet pewien, czy byłoby to w ogóle możliwe, ponieważ biblioteka standardowa tego nie robi. jakiś powód). Pamiętaj, że typ może być wywoływalny ze względu na wiele różnych właściwości - może mieć funkcję konwersji do funkcji typu wskaźnika itp. Pisanie klasy SFINAE, która może sprawić, że ta praca będzie oznaczać odrzucenie niejawnej konwersji w niektórych przypadkach i zaakceptowanie niejawnej konwersji w inne przypadki oparte na naprawdę nieoczywistych właściwościach.

Jeśli chcesz uniknąć tej niejednoznaczności, chciałbym po prostu wybrać inną nazwę funkcji lub jeśli jest to jednorazowy problem, wykonaj odlewanie po stronie dzwoniącego.

+1

Stare pytanie, ale dla przyszłych czytelników istnieje raport o usterce dotyczący 'std :: function'. Zobacz [2132. std :: function ambiguity] (http://cplusplus.github.io/LWG/lwg-active.html#2132), który jest obecnie zaimplementowany w g ++ 4.8. –

0

dodać to:

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

aktualizacja

template<class A0, ...> 
void func (const A0 &a0, ...) { 
    func(argize(a0), ...); // convert chars to strig, otherwise jut pass 
} 
+0

problem to, kod zostanie faktycznie wygenerowany automatycznie i prawdopodobnie istnieje już wiele przeciążeń, takich jak func (string); func (string, int); func (string, int, boost :: function) i tak dalej. Dodanie char * -overloads niestety nie jest opcją. – denis

+0

@denis zobacz aktualizację – Anycorn

Powiązane problemy