Re: Ещё вариации: несколько функций, операторы
От: Alexander G Украина  
Дата: 08.12.09 14:58
Оценка: 7 (1)
typedef int G (void);

struct X {
  G f1 , f2;
};

struct Y {
  G operator++;
};

int main() {
  X x;
  Y y;
}


забавно.
Русский военный корабль идёт ко дну!
Re[2]: Ещё вариации: несколько функций, операторы
От: rg45 СССР  
Дата: 08.12.09 15:23
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>
AG>  G operator++;
AG>


В первую секунду был легкий ступор, только потом въехал в суть написанного
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Ещё вариации: несколько функций, операторы
От: Alexey F  
Дата: 08.12.09 15:37
Оценка: 15 (2)
Здравствуйте, Alexander G, Вы писали:

AG>
[...skip...]
AG>struct Y {
AG>  G operator++; // gcc (mingw) 4.4.1 - error: declaration of 'operator++' as non-function
AG>};
[...skip...]
AG>

Не сработало

AG>забавно.

Да, можно было бы вообще вот так забавляться:
struct Y {
    form<Y>::prefix operator++;
    form<Y>::postfix operator++;
};


Re[3]: Ещё вариации: несколько функций, операторы
От: Alexander G Украина  
Дата: 08.12.09 15:52
Оценка:
Здравствуйте, Alexey F, Вы писали:

AF>Здравствуйте, Alexander G, Вы писали:


AG>>
AF>[...skip...]
AG>>struct Y {
AG>>  G operator++; // gcc (mingw) 4.4.1 - error: declaration of 'operator++' as non-function
AG>>};
AF>[...skip...]
AG>>

AF>Не сработало

Жаль, comeau, borland и msvc осилили

AG>>забавно.

AF>Да, можно было бы вообще вот так забавляться:
struct Y {
  form<Y>::prefix operator++;
  form<Y>::postfix operator++;
};




Интересная мысль, действительно более читабельные ++ и -- и не забудешь вернуть ссылку.

Даже так:
struct Y {
  form<Y>::prefix operator++, operator--;
  form<Y>::postfix operator++, operator--;
};
Русский военный корабль идёт ко дну!
Re[6]: доигрались
От: Pavel Dvorkin Россия  
Дата: 09.12.09 08:17
Оценка: -1
Здравствуйте, rg45, Вы писали:

R>Тебя удивляет, что компилятор не возражает против определения чисто виртуальной функции?


Возражает


class A{
    virtual void f() = 0;
};

void A::f()
{
}

int main()
{
    A a;
    return 0;
}


1>e:\45555252\1.cpp(11) : error C2259: 'A' : cannot instantiate abstract class

1> due to following members:
1> 'void A::f(void)' : is abstract
1> e:\45555252\1.cpp(2) : see declaration of 'A::f'


>Ты еще больше удивишься когда узнаешь, что это полностью соответствет стандарту, см. 10.4/2.


Значит, VC 2008 не соответствует стандарту


>Этот вопрос не раз обсуждался на форума и в Q&A есть ссылка: А чисто виртуальные деструкторы &mdash; бывают?
Автор: Павел Кузнецов
Дата: 03.04.03
.А еще можешь переделать свой пример для "традиционнго" объявления, ты убедишься, что в этом случае можно определить чисто виртуальную функцию. Только, на всякий случай, определение чисто виртуальной функции болжно быть выполнено за пределами определения класса согласно все тому же пункту стандарта.


Как видишь, в VC2008 нельзя.
With best regards
Pavel Dvorkin
Re[7]: доигрались
От: rg45 СССР  
Дата: 09.12.09 09:02
Оценка: +4
Здравствуйте, Pavel Dvorkin, Вы писали:

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


R>>Тебя удивляет, что компилятор не возражает против определения чисто виртуальной функции?


PD>Возражает


1>>e:\45555252\1.cpp(11) : error C2259: 'A' : cannot instantiate abstract class

1>> due to following members:
1>> 'void A::f(void)' : is abstract
1>> e:\45555252\1.cpp(2) : see declaration of 'A::f'


>>Ты еще больше удивишься когда узнаешь, что это полностью соответствет стандарту, см. 10.4/2.


PD>Значит, VC 2008 не соответствует стандарту


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


PD>Как видишь, в VC2008 нельзя.


Ну у нас получается разговор слепого с глухим, честное слово. Обрати внимание на выделенные фразы. Я говорю: "можно определять чисто виртуальные функции", а ты мне возражаешь: "нет, объекты абстрактных классов создавать нельзя" . На самом деле оба эти утверждения верны и друг другу не противоречат. Объекты абстрактных классов действительно нельзя создавать, но при этом можно давать определения чисто виртуальных функций классов этих объектов.

А все недоразумение началось из-за неполноты приведенного тобой примера: здесь
Автор: Pavel Dvorkin
Дата: 08.12.09
. По этому фрагменту и комментариям в нем можно сделать только один вывод, что ты не знаешь о том, что у чисто виртуальных функций могут быть определения. Но, как я теперь уже понимаю благодаря постам других участников, ты хотел именно сказать о глюках майкрософтовских компиляторов, которые пропускают создание объектов абстрактных классов. Это действительно ценные сведения, спасибо.
--
Справедливость выше закона. А человечность выше справедливости.
Re: Вариации на тему деклараций
От: Юрий Жмеренецкий ICQ 380412032
Дата: 09.12.09 18:15
Оценка: 7 (1)
Здравствуйте, rg45, Вы писали:


R>Как вы считаете, имеет ли какой-нибудь смысл, например, такое объявление:

R>
R>typedef int Foo(const char*) const;
R>

R>и в какой области такое объявление может располагаться? Оказывается, имеет и может располагаться вне определения класса, не смотря на модификатор const.

Кстати, в Active Issue 547 предлагается ослабить ограничение на допустимые места, в которых можно использовать квалификатор const и разрешить такое:

template<class T> struct X;

// partial specialization for a const member function:
template<class R> struct X< R() const > 
{};



R>А вот пункт стандарта, который все это благословляет: 9.3/9.


Не совсем: 8.3.5/4 разрешает использование cv-qualifier в typedef declaration для top-level function type, а 8.3.5/7 разрешает использовать объявленные таким образом имена при объявлении функций-членов. С volatile такой фокус также проходит.
Re[4]: Ещё вариации: несколько функций, операторы
От: yatagarasu Беларусь  
Дата: 10.12.09 20:05
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, Alexey F, Вы писали:


AF>>Здравствуйте, Alexander G, Вы писали:


AG>>>
AF>>[...skip...]
AG>>>struct Y {
AG>>>  G operator++; // gcc (mingw) 4.4.1 - error: declaration of 'operator++' as non-function
AG>>>};
AF>>[...skip...]
AG>>>

AF>>Не сработало

AG>Жаль, comeau, borland и msvc осилили


просвятите, а кто прав?
Re[5]: Ещё вариации: несколько функций, операторы
От: rg45 СССР  
Дата: 10.12.09 20:19
Оценка:
Здравствуйте, yatagarasu, Вы писали:

AG>>>>
AG>>>>struct Y {
AG>>>>  G operator++; // gcc (mingw) 4.4.1 - error: declaration of 'operator++' as non-function
AG>>>>};
AG>>>>

AG>>Жаль, comeau, borland и msvc осилили

Y>просвятите, а кто прав?


Рассмотрим все тот же пример из стандарта, п.9.3/9 (сокращено):
typedef void fv(void);
struct S {
fv memfunc1; // equivalent to: void memfunc1(void);
};


Согласно этому:
typedef int G (void);
struct Y {
  G operator++; // equivalent to: int operator++(void);
};


Конечно, сигнатура префиксного оператора инкремента выбрана не совсем удачно, но компилироваться-то должно.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: Вариации на тему деклараций
От: Юрий Жмеренецкий ICQ 380412032
Дата: 11.12.09 00:17
Оценка: 8 (1) +1
Здравствуйте, rg45, Вы писали:

R> А выглядит, конечно, непривычно:

R>
R>struct A
R>{
R>  virtual Foo foo = 0;
R>};
R>

Можно пойти дальше:

struct A
{
  typedef int X();
  typedef int Y() const;
  template<class> X Z;
  template<class> Y Z;
};
Re: +Параметры по-умолчанию
От: Alexey F  
Дата: 11.12.09 00:40
Оценка:
Здравствуйте, rg45, Вы писали:

...И, конечно же , такое:
// Называется "попробуй не специально сделать различные параметры по-умолчанию у предка
// и наследника в виртуальных функциях при соблюдении такого синтаксиса":
typedef void SomeMethod ( int = 42 ) const;


struct A {
    virtual SomeMethod m = 0;
};


struct B : A {
    virtual SomeMethod m;
};


void B::m ( int ) const {

}

ИМХО, такие typedef-ы (я не про параметры по-умолчанию, а вообще) — очень крутая фича
Re[2]: +Параметры по-умолчанию
От: Юрий Жмеренецкий ICQ 380412032
Дата: 11.12.09 00:59
Оценка: 13 (2)
Здравствуйте, Alexey F, Вы писали:

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


AF>...И, конечно же , такое:

AF>
AF>// Называется "попробуй не специально сделать различные параметры по-умолчанию у предка
AF>// и наследника в виртуальных функциях при соблюдении такого синтаксиса":
AF>typedef void SomeMethod ( int = 42 ) const;


AF>struct A {
AF>    virtual SomeMethod m = 0;
AF>};


AF>struct B : A {
AF>    virtual SomeMethod m;
AF>};


AF>void B::m ( int ) const {

AF>}
AF>

AF>ИМХО, такие typedef-ы (я не про параметры по-умолчанию, а вообще) — очень крутая фича

Параметры по умолчанию (как и exception specification) не могут быть использованы в таком контексте (8.3.6/3, 15.4/1).
Re[8]: доигрались
От: Pavel Dvorkin Россия  
Дата: 11.12.09 06:24
Оценка:
Здравствуйте, rg45, Вы писали:


R>А все недоразумение началось из-за неполноты приведенного тобой примера: здесь
Автор: Pavel Dvorkin
Дата: 08.12.09
. По этому фрагменту и комментариям в нем можно сделать только один вывод, что ты не знаешь о том, что у чисто виртуальных функций могут быть определения.


Определения быть могут, и это я знаю, но от того, что у чисто виртуальной функции появится определение, класс, содержащий такую функцию, не перестанет быть абстрактным , и инстансы его создавать нельзя. VC 2008 вполне следует этому правилу для явно описанных чисто виртуальных функций и не следует для описанных через этот самый typedef.


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


Дело не в том, что он пропускает. Он не считает этот класс абстрактным!!!


class A {
    virtual void f() = 0;
};

void A::f()
{
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    return 0;
}


Описание чисто вирт. функции есть, но тем не менее класс абстрактный

1>e:\4111111\4111111.cpp(16) : error C2259: 'A' : cannot instantiate abstract class

1> due to following members:
1> 'void A::f(void)' : is abstract
1> e:\4111111\4111111.cpp(7) : see declaration of 'A::f'

А теперь


typedef void F(void);

class A {
    virtual F f = 0;
};

void A::f()
{
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    return 0;
}


и программа замечательно начинает выполняться и экземпляр A a нормально создается!
With best regards
Pavel Dvorkin
Re[9]: доигрались
От: rg45 СССР  
Дата: 12.12.09 23:51
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Дело не в том, что он пропускает. Он не считает этот класс абстрактным!!!


Не пойму я что-то. Каковы отличительные признаки "допускает создание объектов абстрактного класса" от "не считает класс абстрактным"?
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: доигрались
От: Pavel Dvorkin Россия  
Дата: 14.12.09 02:26
Оценка:
Здравствуйте, rg45, Вы писали:

R>Не пойму я что-то. Каковы отличительные признаки "допускает создание объектов абстрактного класса" от "не считает класс абстрактным"?


А что же тут непонятного ? Если компилятор считает, что класс абстрактный, но при этом допускает создание экземпляров — это одно, это явная ошибка компилятора. Если же компилятор не считает класс абстрактным, тогда создавать экземпляры он имеет полное право, а вопрос же — верно ли он так считает ?
With best regards
Pavel Dvorkin
Re: Вариации на тему деклараций
От: sokel Россия  
Дата: 14.12.09 14:06
Оценка:
Здравствуйте, rg45, Вы писали:

R>...


Хм... можно тип функций шаблоном параметризовать:
#include <stdio.h>

template<typename T> struct t_foo { typedef void foo(T); };

struct A
{
    t_foo<int>::foo bar;
    t_foo<const char*>::foo bar;
};

void A::bar(int v) { printf("A::bar:%d\n", v); }
void A::bar(const char* v) { printf("A::bar:'%s'\n", v); }

int main()
{
    A test;
    test.bar(3);
    test.bar("str");
}


а на шаблонах можно и частичную специализацию сделать :
#include <stdio.h>

template<typename T> struct t_foo { typedef void foo(const T&);  };
template<> struct t_foo<const char*> { typedef void foo(const char*); };

template<typename T> struct A
{
    static typename t_foo<T>::foo bar;
};

template<> void A<int>::bar(const int& v) { printf("A::bar:%d\n", v); }
template<> void A<const char*>::bar(const char* v) { printf("A::bar:'%s'\n", v); }

int main()
{
    A<int>::bar(3);
    A<const char*>::bar("str");
}


зачем вот только, непонятно...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.