Вопрос по стандарту по поводу Name lookup
От: Dmitriev Sergey Victorovich Россия  
Дата: 17.05.03 04:29
Оценка:
Доброго времени суток!
Объясните мне, pls, с точки зрения стандарта, почему следующий код не компилируется?

struct X
{
  template<typename T, typename TT>
  void RR(T t)
  {
    static_cast<TT*>(this)->R(t);
  }
};

struct a {   void R(int) {} };

struct b {   void R(float) {} };

struct d : X, a, b
{
  void foo()
  {
    RR<int,a>(2);
    RR<float,b>(2.0f);
   }
};

int main() { d().foo(); }

Сomeau выдает следующее:


Что говорит VC 7 писать не буду
Ошибку я обошел, введя третий параметр template:

struct X
{
  template<typename T, typename TT, typename TTT>
  void RR(T t)
  {
    static_cast<TT*>(static_cast<TTT*>(this))->R(t);
  }
};


и, соответственно, подправив foo():

struct d : X, a, b
{
  void foo()
  {
    RR<int,a,d>(2);
    RR<float,b,d>(2.0f);
   }
};


Но мне не понятно, почему же в первом случае компилятор не смог найти функцию, например, static_cast<a*>(d*)->R(int) ?
Может я чего-то сильно не понимаю?
Re: Вопрос по стандарту по поводу Name lookup
От: Павел Кузнецов  
Дата: 17.05.03 11:06
Оценка:
Здравствуйте, Dmitriev Sergey Victorovich, Вы писали:

DSV> Доброго времени суток!

DSV> Объясните мне, pls, с точки зрения стандарта, почему следующий код
DSV> не компилируется?

DSV>
DSV> struct X
DSV> {
DSV>   template<typename T, typename TT>
DSV>   void RR(T t)
DSV>   {
DSV>     static_cast<TT*>(this)->R(t);
DSV>   }
DSV> };

DSV> struct a {   void R(int) {} };

DSV> struct b {   void R(float) {} };

DSV> struct d : X, a, b
DSV> {
DSV>   void foo()
DSV>   {
DSV>     RR<int,a>(2);
DSV>     RR<float,b>(2.0f);
DSV>    }
DSV> };
DSV>


Давай самостоятельно "проинстанциируем" шаблон, скажем, для случая RR<int,a>(2):

struct X
{
  void RR_int_a(int t)
  {
    static_cast<a*>(this)->R(t);
  }
};


Таким образом, специализация RR<int, a> пробует привести указатель X* к типу a*,
используя для этого static_cast. Т.к. типы X и a между собой никак не связаны,
естественно, это не разрешено.
Posted via RSDN NNTP Server 1.5 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Вопрос по стандарту по поводу Name lookup
От: Bell Россия  
Дата: 19.05.03 06:32
Оценка: -1
Здравствуйте, Dmitriev Sergey Victorovich, Вы писали:

DSV>Доброго времени суток!

DSV>Объясните мне, pls, с точки зрения стандарта, почему следующий код не компилируется?

DSV>[ccode]

DSV>struct X
DSV>{
DSV> template<typename T, typename TT>
DSV> void RR(T t)
DSV> {
DSV> reinterpret_cast<TT*>(this)->R(t);
DSV> }
DSV>};
Любите книгу — источник знаний (с) М.Горький
Re[2]: Вопрос по стандарту по поводу Name lookup
От: Dmitriev Sergey Victorovich Россия  
Дата: 19.05.03 06:51
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Таким образом, специализация RR<int, a> пробует привести указатель X* к типу a*,

ПК>используя для этого static_cast. Т.к. типы X и a между собой никак не связаны,
ПК>естественно, это не разрешено.

Я прошу прощения за неверно приведенный пример. Писал после бессонной ночи и прошу сильно ногами не пинать. В таком варианте вопрос превратился в нелепость.
На самом деле имелся ввиду следуюший пример:

struct X
{
  template<typename T, typename TT>
  void RR(T t)
  {
    static_cast<TT*>(this)->R(t);
  }
};

struct a { void R(int) {} };

struct b { void R(float) {} };

struct d : X, a, b
{
  void foo()
  {
    RR<int,d>(2);
    RR<float,d>(2.0f);
   }
};

int main()
{
  d().foo();
}

Cameau ругнулся следующим образом.
Comeau C/C++ 4.3.1 (Mar  1 2003 20:09:34) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 6: error: "d::R" is ambiguous
      static_cast<TT*>(this)->R(t);
                              ^
          detected during instantiation of
                    "void X::RR<T,TT>(T) [with T=int, TT=d]" at line 18

"ComeauTest.c", line 6: error: "d::R" is ambiguous
      static_cast<TT*>(this)->R(t);
                              ^
          detected during instantiation of
                    "void X::RR<T,TT>(T) [with T=float, TT=d]" at line 19

2 errors detected in the compilation of "ComeauTest.c".


Вот что я хотел спросить. Собственно откуда берется "ambiguous", если перегрузка функций должна однозначно указать на конкретную функцию? Вот еще более непонятный пример:
struct X
{
  template<typename T, typename TT>
  void RR(T t)
  {
    static_cast<TT*>(this)->R(t);
  }
};

struct a { void R(int) {} };

struct b { typedef double R; };

struct d : X, a, b
{
  void foo()
  {
    RR<int,d>(2);
   }
};

int main()
{
  d().foo();
}

"Ответ" Cameau :
Comeau C/C++ 4.3.1 (Mar  1 2003 20:09:34) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing.  All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 6: error: "d::R" is ambiguous
      static_cast<TT*>(this)->R(t);
                              ^
          detected during instantiation of
                    "void X::RR<T,TT>(T) [with T=int, TT=d]" at line 18

1 error detected in the compilation of "ComeauTest.c".
Re[2]: Вопрос по стандарту по поводу Name lookup
От: Dmitriev Sergey Victorovich Россия  
Дата: 19.05.03 06:58
Оценка:
Здравствуйте, Bell.
Спасибо за ответ, но я, к сожалению, спросил не то, что хотел узнать . Прошу извинить. Настоящий вопрос находиться в моем ответе Павлу Кузнецову.
Re: Вопрос по стандарту по поводу Name lookup
От: Lorenzo_LAMAS  
Дата: 19.05.03 07:05
Оценка:
DSV>struct X
DSV>{
DSV>  template<typename T, typename TT>
DSV>  void RR(T t)
DSV>  {
DSV>    static_cast<TT*>(this)->R(t);
DSV>  }
DSV>};

DSV>struct a {   void R(int) {} };

DSV>struct b {   void R(float) {} };

DSV>struct d : X, a, b
DSV>{
DSV>  void foo()
DSV>  {
DSV>    RR<int,a>(2);//*
DSV>    RR<float,b>(2.0f);//**
DSV>   }
DSV>};

DSV>int main() { d().foo(); }

Поиск имен тут не при чем. * — ты пытаешься привести X * к а * — это невозможно, так как а не произвоен от Х. Аналогично с **
Of course, the code must be complete enough to compile and link.
Re[3]: Вопрос по стандарту по поводу Name lookup
От: Lorenzo_LAMAS  
Дата: 19.05.03 07:08
Оценка:
Да, это серьезно отличается от исходного примера. Имя R — неоднозначно, потому как ты его поучаешь дважды из двух классов.
Of course, the code must be complete enough to compile and link.
Re[4]: Вопрос по стандарту по поводу Name lookup
От: Dmitriev Sergey Victorovich Россия  
Дата: 19.05.03 07:20
Оценка:
Я считал, что мой пример эквивалентет следующему:
struct X
{
  template<typename T, typename TT>
  void RR(T t)
  {
    static_cast<TT*>(this)->R(t);
  }
};

struct d : X
{
  void R(int) {}
  void R(float);
  void foo()
  {
    RR<int,d>(2);
    RR<float,d>(2.0f);
   }
};

int main()
{
  d().foo();
}


Я согласен с тем, что функции void R() две, но сигнатуры-то у них разные!
Или я опять не выспался?
Re[5]: Вопрос по стандарту по поводу Name lookup
От: Lorenzo_LAMAS  
Дата: 19.05.03 07:26
Оценка:
DSV>Я считал, что мой пример эквивалентет следующему:
DSV>struct X
DSV>{
DSV>  template<typename T, typename TT>
DSV>  void RR(T t)
DSV>  {
DSV>    static_cast<TT*>(this)->R(t);
DSV>  }
DSV>};

DSV>struct d : X
DSV>{
DSV>  void R(int) {}
DSV>  void R(float);
DSV>  void foo()
DSV>  {
DSV>    RR<int,d>(2);
DSV>    RR<float,d>(2.0f);
DSV>   }
DSV>};

DSV>int main()
DSV>{
DSV>  d().foo();
DSV>}


Ты постоянно меняешь условия. R у тебя в одном из классов — typedef'ом был. Но это не важно. То, что ты в вопросе (исправленном) не эквивалентно тому что написано выше. До сигнатуры тут дело не доходит. Смотри clause 10 стандарта (там, по-моему)
Of course, the code must be complete enough to compile and link.
Re[6]: Вопрос по стандарту по поводу Name lookup
От: Dmitriev Sergey Victorovich Россия  
Дата: 19.05.03 09:54
Оценка:
Да, действительно, нашел: 10.2 Member name lookup — там пример прямо для моего случая.
Спасибо за ответы ( и терпение ).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.