2016-07-21 4 views
0

C++ У меня есть проблема с пониманием, как функция перегрузки работы, она сводится к этому простому примеру:неявного преобразования для согласования перегрузок

class Foo { 
public: 
    void bar(const bool & val) {} 
}; 

void DoFn(std::function<void(Foo*, const wxString&)> fn) {} 

, если я теперь называю DoFn так:

DoFn(&Foo::bar); 

это компилирует штраф. Как это преобразование из bool в wxString в параметр шаблона для std :: function? Если я изменю wxString на std :: string, тогда он не скомпилируется, как ожидалось.

(wxString класс в WxWidgets, версия 2.8)

То, что я действительно не понимаю, как класс wxString может объявить его можно преобразовать в из BOOL.

Я попытался сделать класс следующим образом:

class FakeString { 
public: 
    FakeString(bool) {}; 
    FakeString(const bool &){}; 
}; 

и замена wxString в DoFn с FakeString, но он не компилируется говоря:

could not convert '&Foo::bar' from 'void (Foo::*)(const bool&)' to 'std::function<void(Foo*, const FakeString&)>' 
+0

Можете ли вы предоставить действующий рабочий код? Вы абсолютно уверены, что нет другой версии 'bar', которая принимает' wxString', которую вы пропустили? – Smeeheey

+0

Я скомпилировал этот код –

+0

Ну, это не мог быть буквально этот код как отсутствующий '#include '. Вы говорите, что это единственная разница? – Smeeheey

ответ

6

Вы получили неправильный порядок преобразования: Речь идет о преобразовании wxStrging в bool, а не в другом направлении.

class FakeString { 
public: 
    operator bool() const { return false; } 
}; 

wxString не имеет оператора преобразования BOOL, но что-то подобное: неявное преобразование в const char*:

class FakeString { 
public: 
    operator const char*() const { return nullptr; } 
}; 

Если вы построили WxWidgets с wxUSE_STL установлен в 1, неявные преобразования в обе узкие и широкие строки C отключены, а заменены неявными преобразованиями в std :: string и std :: wstring.

И these - это методы wxString, которые вы ищете, операторы преобразования указателей.

+0

'DoFn' вызывается с' & Foo :: bar', который является 'void (Foo :: *) (const bool &)', который необходимо отправить в 'std :: function ', поэтому' const bool & 'необходимо выставить в' const wxString & '. Я ошибаюсь? –

+1

@ Антон 'std :: function' делает стирание и основан на действительном использовании, а не подписи. Так что, пока функция вызывается с помощью 'Foo *' и 'const wxString &', все в порядке. – TartanLlama

+0

Однако я не вижу неявного оператора преобразования bool; связанный с «operator!». Может, я просто что-то упустил? – TartanLlama

0

Я думаю, что может возникнуть некоторая путаница вокруг синтаксиса std::function. Есть ли причина, почему вы не просто делать

struct Foo { 
    void bar(const bool & val) {} 
}; 

void DoFn(std::function<void(const bool&)> fn) {} 

и затем

Foo foo = Foo(); 
DoFn(&foo::bar); 

Что вы объявляете это функция, принимающая Foo* и WxString аргумент. Я не думаю, что это то, что вы хотите. В отличие от языков, подобных Python, в C++ вы не можете явно передать указатель this. Синтаксис для нестатического указателя функции функции, возвращающего void, будет void(Foo::*)(const bool&). Я предполагаю, что компилятор не жалуется, потому что функция с правильной подписью случайно попадает в сферу действия.

+0

Вы можете передать это явно. В DoFn в моем вопросе вы можете вызвать fn (Foo(), wxString()), и было бы правильно –

+0

Ну, 'fn (Foo(), wxString())' - функция, принимающая 'Foo' и 'wxString' (или cons refs). Это не указатель 'this'. 'this' внутри' Foo :: bar' имеет тип '* Foo'. Я думаю, вы сбиваете с толку. – dirkster

+0

Извините, что я опубликовал этот комментарий быстро, по моему мнению, вы можете взять ссылку на функцию-член и вызвать ее с любым указателем, который имеет правильный тип. от верхней части головы это может быть «Foo f; wxString s; fn (&f, s);) –

Смежные вопросы