2015-05-16 2 views
1

Следующий код компилируется в каждом компиляторе, который я пробовал (gcc 4.9.2, clang 3.6 и VS 2015). Однако VS 2013 обновляет 4 craps с ошибкой, которую я подробно рассмотрю ниже. Это ошибка в компиляторе?Оператор вызова константы, вызывающий связанную функцию non-const member

#include <iostream> 
#include <functional> 

template<typename Func> 
struct Bar 
{ 
    Func f_; 
    Bar(Func f) : f_(f) { } 
    void operator()() const 
    { 
     f_(); 
    } 
}; 

template<typename T> 
void Baz(T const& t) 
{ 
    Bar<T> b(t); 
    b(); 
} 

struct Foo 
{ 
    Foo() 
    { 
     auto r = std::bind(&Foo::DoFoo, this); 
     Baz(r); 
    } 
    void DoFoo() { std::cout << "Doing Foo!\n"; } 
}; 

int main() 
{ 
    Foo f; 
    return 0; 
} 

список ошибок следующим образом:

1>doodle.cpp(15): error C3848: expression having type 'const std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const >' would lose some const-volatile qualifiers in order to call 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const >::operator()<>(void)' 
1>   doodle.cpp(14) : while compiling class template member function 'void Bar<T>::operator()(void) const' 
1>   with 
1>   [ 
1>    T=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const > 
1>   ] 
1>   doodle.cpp(23) : see reference to function template instantiation 'void Bar<T>::operator()(void) const' being compiled 
1>   with 
1>   [ 
1>    T=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const > 
1>   ] 
1>   doodle.cpp(22) : see reference to class template instantiation 'Bar<T>' being compiled 
1>   with 
1>   [ 
1>    T=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const > 
1>   ] 
1>   doodle.cpp(31) : see reference to function template instantiation 'void Baz<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const >>(const T &)' being compiled 
1>   with 
1>   [ 
1>    T=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Foo::*)(void),void,Foo,>,Foo *const > 
1>   ] 

Я думал, что хотел DoFoo() будет константная функция член, но фиксирующее это не помогло.

+1

это компилируется, если я изменить его на: 'станд :: функции г = зЬй :: Bind (& Foo :: DoFoo, это);' – doqtor

+0

@doqtor это интересно тин. Автоматическая дедукция идет с трудом. Я попробую и отчитаю. Благодаря! – ForeverLearning

ответ

1

Это, кажется, в VS2013 компилятора ошибка и есть 2 способа работы вокруг него:

Использование станд :: Функция вместо автоматического чтобы хранить вызов функции члена

std::function<void()> r = std::bind(&Foo::DoFoo, this); 

Или удалить сопзЬ от оператора вызова функции() в баре

template<typename Func> 
struct Bar 
{ 
    Func f_; 
    Bar(Func f) : f_(f) { } 
    void operator()() // const 
    { 
     f_(); 
    } 
}; 
+0

Оператор() вышел из-под контроля. Явное указание типа возврата работает! – ForeverLearning

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