Непонятки с using Base::func в производном классе...
От: Аноним  
Дата: 13.12.07 19:07
Оценка:
Иеется код:

class Base
{
public:
protected:
    void test();
};

class Derived : public Base
{
public:
    using Base::test;
};


int main()
{
    using namespace std;
    Derived d;
    d.test();
    vector<Derived> v;
    &Derived::test;
    for_each(v.begin(), v.end(), mem_fun_ref(&Derived::test));
}

компилятор ругается на выделенных строках на: cannot access protected member declared in class 'Base'.
Объясните плз, в чем трабла?
Re: Непонятки с using Base::func в производном классе...
От: Константин Л.  
Дата: 13.12.07 19:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Иеется код:


[]

А>int main()

А>{
А> using namespace std;
А> Derived d;
А> d.test();
А> vector<Derived> v;
А> &Derived::test;
А> for_each(v.begin(), v.end(), mem_fun_ref(&Derived::test));

А>}
А>[/ccode]
А>компилятор ругается на выделенных строках на: cannot access protected member declared in class 'Base'.
А>Объясните плз, в чем трабла?

Про стандарт не скажу, но если рассуждать логически, то и на d.test() он тоже должен ругаться
Re: Непонятки с using Base::func в производном классе...
От: _Dreamer Россия  
Дата: 14.12.07 04:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Иеется код:


А>компилятор ругается на выделенных строках на: cannot access protected member declared in class 'Base'.

А>Объясните плз, в чем трабла?

Мне кажется это баг.
Почему я так думаю — раз был указан access declaration в производном классе, и вызов
d.test();

вполне законен, то и доступ по указателю тоже должен быть. однако это не так в случае MSVC(7.1 и 8-SP1).
class Base
{
public:
protected:
    void test(){}

    int a;
};

class Derived : public Base
{
public:
    using Base::test;
    using Base::a;
    //Base::a;
};


void mem_fun_test()
{
    Derived d;
    d.test();
    d.a = 10;
    int Derived::* pa = &Derived::a;

    d.*pa = 100;
    void (Derived::* f)() =  &Derived::test;    
}

результат —

Compiling...
main.cpp
c:\...\main.cpp(31) : error C2248: 'Base::test' : cannot access protected member declared in class 'Base'
c:\...\main.cpp(9) : see declaration of 'Base::test'
c:\...\main.cpp(6) : see declaration of 'Base'
Build log was saved at "file://c:\...\BuildLog.htm"
mem_fun_test — 1 error(s), 0 warning(s)


хотя, если добавить аналогичный код, но не для метода Base, а для его члена, то тут возражений нет, как видно.
к тому же, Comeau Online код успешно скомпилировал.

Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

Re[2]: Непонятки с using Base::func в производном классе...
От: _Dreamer Россия  
Дата: 14.12.07 04:34
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>Про стандарт не скажу, но если рассуждать логически, то и на d.test() он тоже должен ругаться


почему он должен на это ругаться ?
Re[2]: Непонятки с using Base::func в производном классе...
От: Аноним  
Дата: 14.12.07 06:16
Оценка:
Здравствуйте, _Dreamer, Вы писали:

_D>Здравствуйте, Аноним, Вы писали:


А>>Иеется код:


А>>компилятор ругается на выделенных строках на: cannot access protected member declared in class 'Base'.

А>>Объясните плз, в чем трабла?

_D>Мне кажется это баг.

_D>Почему я так думаю — раз был указан access declaration в производном классе, и вызов
_D>
_D>d.test();
_D>

_D>вполне законен, то и доступ по указателю тоже должен быть. однако это не так в случае MSVC(7.1 и 8-SP1).
_D>[ccode]

я тоже так подумал когда BCB не скомпилил приведенный пример, но когда 2005 и 2008 студия руганулись таким же образом я засомневалси...
Re: Непонятки с using Base::func в производном классе...
От: dsilence  
Дата: 14.12.07 08:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Иеется код:


А>
А>class Base
А>{
А>public:
А>protected:
А>    void test();
А>};

А>class Derived : public Base
А>{
А>public:
А>    using Base::test;
А>};


А>int main()
А>{
А>    using namespace std;
А>    Derived d;
А>    d.test();
А>    vector<Derived> v;
А>    &Derived::test;
А>    for_each(v.begin(), v.end(), mem_fun_ref(&Derived::test));
А>}
А>

А>компилятор ругается на выделенных строках на: cannot access protected member declared in class 'Base'.
А>Объясните плз, в чем трабла?

всё честно. нет объекта — нет синонима.
Re[3]: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 14.12.07 08:20
Оценка:
Все же это баг.
Of course, the code must be complete enough to compile and link.
Re[2]: Непонятки с using Base::func в производном классе...
От: Аноним  
Дата: 14.12.07 15:05
Оценка:
Здравствуйте, dsilence, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


D>всё честно. нет объекта — нет синонима.


Re[3]: Непонятки с using Base::func в производном классе...
От: dsilence  
Дата: 14.12.07 17:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, dsilence, Вы писали:


D>>Здравствуйте, Аноним, Вы писали:


D>>всё честно. нет объекта — нет синонима.


А>


стандарт. пункт 7.3.3 параграф 13.
Re[4]: Непонятки с using Base::func в производном классе...
От: dsilence  
Дата: 14.12.07 17:50
Оценка:
Здравствуйте, dsilence, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, dsilence, Вы писали:


D>>>Здравствуйте, Аноним, Вы писали:


D>>>всё честно. нет объекта — нет синонима.


А>>


D>стандарт. пункт 7.3.3 параграф 13.


For the purpose of overload resolution, the functions which a introduced by a using-declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function and in all other respects the function remains a member of the base class


пара последних предложений.
Re[5]: Непонятки с using Base::func в производном классе...
От: Аноним  
Дата: 14.12.07 18:51
Оценка:
Здравствуйте, dsilence, Вы писали:

D>>стандарт. пункт 7.3.3 параграф 13.


D>пара последних предложений.


хм, спасибо. т.е. все в соответствии со стандартом...
как же быть тогда? уж и не прикалывает создавать дубли функции в таких случаях... остается сделать открытой в базовом классе...
Re[5]: Непонятки с using Base::func в производном классе...
От: Аноним  
Дата: 14.12.07 19:11
Оценка:
D>>стандарт. пункт 7.3.3 параграф 13.

и получается, что Comeau неправильно компилит?
Re[5]: Непонятки с using Base::func в производном классе...
От: De Bug Финляндия  
Дата: 18.12.07 06:54
Оценка:
Здравствуйте, dsilence, Вы писали:

D>>стандарт. пункт 7.3.3 параграф 13.


D>

D>For the purpose of overload resolution, the functions which a introduced by a using-declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function and in all other respects the function remains a member of the base class


D>пара последних предложений.


Объясни, пожалуйста, как эта цитата связана с исходным примером и как она объясняет ошибки компиляции?
Re[6]: Непонятки с using Base::func в производном классе...
От: dsilence  
Дата: 18.12.07 12:04
Оценка:
Здравствуйте, De Bug, Вы писали:

DB>Здравствуйте, dsilence, Вы писали:


D>>>стандарт. пункт 7.3.3 параграф 13.


D>>

D>>For the purpose of overload resolution, the functions which a introduced by a using-declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function and in all other respects the function remains a member of the base class


D>>пара последних предложений.


DB>Объясни, пожалуйста, как эта цитата связана с исходным примером и как она объясняет ошибки компиляции?


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

&Derived::test;


в данном случае объект не создан соответственно никакого this нет. остаётся вторая часть фразы , что подтверждают ошибки

error C2248: 'Base::test' : cannot access protected member declared in class 'Base'
Re[7]: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 18.12.07 12:56
Оценка:
Вообще-то, этот пункт совсем некстати ты упомянул. Хинт — читай внимательнее, там ясно сказано, для целей разрешения перегрузки. Ничего о доступе к именам тут нет и в помине.
Of course, the code must be complete enough to compile and link.
Re[8]: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 18.12.07 13:10
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Вообще-то, этот пункт совсем некстати ты упомянул. Хинт — читай внимательнее, там ясно сказано, для целей разрешения перегрузки. Ничего о доступе к именам тут нет и в помине.


А вот и пример, который, по-моему, подходит к сказанному в 7.3.3/13 (в зависимости от наличия/отсутствия закомментированной строки код не компилируется/компилируется):

class A
{
public:
    A operator + (const A)const;
};

class B : public A
{
public:
   //using A::operator + ;
};

B operator + (const B &, const A &);

int main()
{
   A a;
   B b;
   b + a;
}
Of course, the code must be complete enough to compile and link.
Re[8]: Непонятки с using Base::func в производном классе...
От: dsilence  
Дата: 18.12.07 13:33
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Вообще-то, этот пункт совсем некстати ты упомянул. Хинт — читай внимательнее, там ясно сказано, для целей разрешения перегрузки. Ничего о доступе к именам тут нет и в помине.


позволю себе не согласиться.

struct A{
   virtual void f();
};
struct B: A{
   using A::f;
   void f();
};


вот абсолютно легальный код. предлагаю задуматься о том на каком этапе и какая функция будет вызвана. а механизм вызова и почему он именно такой описан как раз в озвученом пункте.
Re[9]: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 18.12.07 13:48
Оценка:
D>позволю себе не согласиться.

D>
D>struct A{
D>   virtual void f();
D>};
D>struct B: A{
D>   using A::f;
D>   void f();
D>};

//дополним ваш код
int main()
{
   B b;
   b.f();
}
D>


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


А я предлагаю не генерить дополнительных примеров, совсем все запутывающих и уводящих все совсем в другую сторону. Я тебе написал ранее пример, который относится к процитированному тобой пункту 7.3.3/13. Для твоего нового примера подходит пункт 7.3.3/12, но все это опять никак не относится к исходному вопросу и твоим обоснованием правильности поведения неправильных компиляторов.

When a using-declaration brings names from a base class into a derived class scope, member functions in
the derived class override and/or hide member functions with the same name and parameter types in a base
class (rather than conflicting). [Example:
struct B {
virtual void f(int);
virtual void f(char);
void g(int);
void h(int);
};
121
ISO/IEC 14882:2003(E)  ISO/IEC
7.3.3 The usingdeclaration 7 Declarations
struct D : B {
using B::f;
void f(int); // OK: D::f(int) overrides B::f(int);
using B::g;
void g(char); // OK
using B::h;
void h(int); // OK: D::h(int) hides B::h(int)
};
void k(D* p)
{
p->f(1); //calls D::f(int)
p->f(’a’); //calls B::f(char)
p->g(1); //calls B::g(int)
p->g(’a’); //calls D::g(char)
}

Of course, the code must be complete enough to compile and link.
Re[6]: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 18.12.07 13:50
Оценка:
Здравствуйте, Аноним, Вы писали:

D>>>стандарт. пункт 7.3.3 параграф 13.


А>и получается, что Comeau неправильно компилит?

Нет, не получается. Ибо 7.3.3/13 здесь не к месту.
Of course, the code must be complete enough to compile and link.
Re: Непонятки с using Base::func в производном классе...
От: Lorenzo_LAMAS  
Дата: 18.12.07 14:17
Оценка:
Вот есть 7.3.3/15, который говорит

The alias created by the using-declaration has the usual accessibility for a member-declaration.
[Example:
class A {
private:
void f(char);
public:
void f(int);
protected:
void g();
};
class B : public A {
using A::f; // error: A::f(char) is inaccessible
public:
using A::g; // B::g is a public synonym for A::g
};
—end example]


Поэтому, пример:
class Base
{
public:
protected:
    void test();
};

class Derived : public Base
{
public:
    using Base::test;
};


int main()
{
    using namespace std;
    Derived d;
    d.test();
    vector<Derived> v;
    &Derived::test;
    for_each(v.begin(), v.end(), mem_fun_ref(&Derived::test));
}


должен компилиться (ну, при условии, что включены соответствующие заголовки). Например, g++ и Comeau его вполне компилируют.
Of course, the code must be complete enough to compile and link.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.