2013-09-03 3 views
4

Я использую Visual Studio 2010.Получить указатель на метод класса с «помощи» ключевым словом

Почему я не могу получить указатель на метод класса, который был «модернизированный» публика в классе ребенка?

Следующий код не компилируется:

#include <iostream> 
#include <functional> 

class Parent { 
protected: 
    void foo() { 
     std::cout << "Parent::foo()\n"; 
    } 
}; 

class Child : public Parent 
{ 
public: 
    //void foo() { Parent::foo(); } //This compiles 
    using Parent::foo; //This does NOT compile 
}; 
int main() { 
    Child c; 

    std::function < void() > f = std::bind(&Child::foo, &c); 
    f(); 
    return 0; 
} 

Это дает ошибку:

error C2248: 'Parent::foo' : cannot access protected member declared in class 'Parent' 
+0

Это разные методы. использование Parent :: foo делает псевдоним Parent :: foo as Child :: foo, и публика делает это так, чтобы каждый мог получить доступ к псевдониму: он не делает ничего, чтобы изменить Parent :: foo. – IdeaHat

+1

Не знаю, в чем проблема, но, может быть, использовать совместимый компилятор, созданный в этом десятилетии? [См. Это вживую.] (Http://ideone.com/vzEj2y). Вы говорите, что используете VS2010, возможно, обновите его до 2012 года (с ноябрьским 2012 CTP). Или подходящий gcc или clang (но если ваш VS-участник, это маловероятно). – WhozCraig

+0

Код компилируется под TDM-GCC (MINGW) 4.7.1, когда удаляется строка 'std :: function < void() > f = std :: bind (& Child :: foo, &c);' (ошибка: 'function' не является членом станд). –

ответ

3

Он компилирует here.

Я думаю, что вы просто забыли добавить параметр C++ 11 в свой компилятор.

Например, gcc is -std=c++11 или -std=gnu++11.

EDIT: кажется из here, что с использованием псевдонима декларации не реализованы в любой визуальной версии Studio.

Фактически, here некоторые люди говорят о ошибке компилятора .

Странная вещь здесь:

c.foo();             // this works fine 
std::function < void() > f = std::bind(&Child::foo, &c); // this won't compile 
+0

Я использую Visual Studio 2010. Я также тестировал это на Visual Studio 2013 и Visual Studio 2012, но без успеха –

+0

Действительно. Он отлично компилируется с TDM-GCC (MINGW) 4.7.1 с -std = C++ 11. –

+1

@EdisonGustavoMuenz Как говорит мое редактирование, похоже, что использование псевдонима в Visual Studio еще не реализовано. –

0

Этот код компилируется g++ 4.8.1. Вы используете C++ 11? Я получаю следующий результат, когда я его запускаю:

Parent::foo() 
+0

Я использую Visual Studio 2010. Я также тестировал это на Visual Studio 2013 и Visual Studio 2012, но без успеха –

0

В до C++ 11, это 'с помощью' позволяет не скрывать Parent :: Foo в случае, как это:

class Parent 
{ 
protected: 
    void foo() {} 
}; 

class Child : public Parent 
{ 
    using Parent::foo; // without this, following code doesn't compile. 
public: 
    // foo(int) hides Parent::foo without the 'using' 
    void foo(int) { return foo(); } 
}; 
1

По какой-то причине Visual Studio не позволит вам принять адрес foo, хотя он является публичным членом Child, объявленным с использованием простого старого синтаксиса C++ 03.

std::function<void()> f = std::bind(&Child::foo, &c); // won't compile 

auto fp = &Child::foo; // also won't compile 

Непосредственно вызов функции все еще работает отлично:

c.foo(); // compiles OK 

Любопытно, что это означает, что вы используете частичную поддержку VS2010 в C++ 11 для работы вокруг изъян в своей поддержке C++ 03, с использованием лямбда для достижения того же эффекта, что и ваше выражение bind:

std::function<void()> f = [&c]{ c.foo(); }; // compiles OK! 

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

  • Нет связанных вопросов^_^