Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поддержка частичной специализации шаблонов, отсутствует? 
:(
    Опции темы
azesmcar
Дата 26.5.2009, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(vaddsm @  26.5.2009,  21:58 Найти цитируемый пост)
 // Здесь M это адрес - число.

брррр...совсем голова не варит smile не выспался.. smile

Добавлено @ 22:04
vaddsm

Нашел у себя Borland C++ Builder 6.

Код

#include <windows.h>
#include <iostream>

template <class C, void (__stdcall C::*M)()>
class nested
{
};

class A
{
public:
    void __stdcall foo()
    {
        std::cout << "hello world" << std::endl;
    }
};

int main()
{
    nested<A, &A::foo> d;
}


скомпилировал на ура.

Это сообщение отредактировал(а) azesmcar - 26.5.2009, 22:12
PM   Вверх
vaddsm
Дата 26.5.2009, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



Код

template <class C, void (__stdcall C::*M)()>
class nested
{
};

class A
{
   public: void __stdcall foo()
    {
     MessageBox(0,"good!","",0);
    }
};



на MingGW, строка 1: parse error before `)' token 

Код

template <class C, void __stdcall (C::*M)()>


Segmentation fault

Код

template <class C, void (C::*M)()>


ok

Добавлено через 3 минуты и 45 секунд
Причем последняя форма как я уже говорил принимает любое соглашение, и я теряюсь в догадках, каким образом, в таком вот случае, компилятор MinGW знает как именно в nested выполнить такой вот вызов:

(A_instanse->*M)();
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



vaddsm

С Борландом разобрались?
PM   Вверх
vaddsm
Дата 26.5.2009, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



MinGW лол: 

Код

class A
{
   public: void __fastcall foo(int a, int n)
    {
     MessageBox(0,"good!","",0);
    }    
};

template <class C, void (C::*M)(int, int)>
class nested
{
 public:nested()
 {
  A a;
  (a.*M)(1, 2); // Откуда друг ты мой любезный ты знаешь как вызвать M? Загадочный компилятор )
 }; 
};


Работает ))

Да, с борландом все на данный момент ок, в отличие от остальных компиляторов, он требует, указывать конвенцию вызова сразу после типа возвращаемого значения:
Код

<R __stdcall (*)( T0 , T1 , T2 , T3)>

при этом typedef указателя на такого рода функцию такой же как и везде:
Код

typedef R  (__stdcall *lpfn)( T0 , T1 , T2 , T3);

Не логично, как вы думаете?

Добавлено @ 22:36
Спасибо (+1) за ключ к разгадке! Но MinGW меня настораживает и вобще кто из компиляторов прав, я пересмотрел несколько раз стандарт, конкретики в данном вопросе не обнаружил (

Это сообщение отредактировал(а) vaddsm - 26.5.2009, 22:36
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



vaddsm

Скачал MinGW, проверил
Код

#include <windows.h>
#include <iostream>

template <class C, void (__stdcall C::*M)()>
class nested
{
public:
    void call(C* that)
    {
        (that->*M)();
    }
};
class A
{
public:
    void __stdcall foo()
    {
        std::cout << "hello world" << std::endl;
    }
};
int main()
{
    nested<A, &A::foo> d;
    A t;
    d.call(&t);
}


работает..в чем проблема то?
PM   Вверх
vaddsm
Дата 26.5.2009, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



Пост выше. Проблема в том что работает ), серьезно. 
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(vaddsm @  26.5.2009,  22:34 Найти цитируемый пост)
Спасибо (+1) за ключ к разгадке! Но MinGW меня настораживает и вобще кто из компиляторов прав, я пересмотрел несколько раз стандарт, конкретики не обнаружил ( 

конкретики насчет чего? насчет __stdcall? Там ее и не будет, это Microsoft specific keyword.

Добавлено через 3 минуты и 24 секунды
Цитата(vaddsm @  26.5.2009,  22:37 Найти цитируемый пост)
Пост выше. Проблема в том что работает ), серьезно.  

А вызов? Обьект класса nested создается? если нет - то все нормально. Пока не используется шаблон - компилятор не генерирует его код. Если да - можно посмотреть как? может быть опять таки - все нормально.

Код

template <class T>
class V
{
 void f() {
 dfsl;jsdlfjsdfjsdfjdkljfkl
}
}


это тоже будет компилироватся - пока класс V не используется

Это сообщение отредактировал(а) azesmcar - 26.5.2009, 22:41
PM   Вверх
vaddsm
Дата 26.5.2009, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



Так. У меня среда Dev. C++ (MinGW компиллер инсайд). На ваш код
Код

template <class C, void (__stdcall C::*M)()>

ругается матом parse error before `)' token.

Только так:
Код

template <class C, void (C::*M)()>



Затем. Я искал в стандарте информацию не о __stdcall в частности а об указании типов конвенций.

Добавлено через 2 минуты и 14 секунд
В моем примере я вызов делал также
Код

 nested<A, &A::foo> n;


И foo нормально вызывался, хотя не должен бы.
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(vaddsm @  26.5.2009,  22:51 Найти цитируемый пост)
Так. У меня среда Dev. C++ (MinGW компиллер инсайд). На ваш код

Очень очень странно
Код

#include <windows.h>
#include <iostream>
template <class C, void (__stdcall C::*M)()>
class nested
{
public:
    void call(C* that)
    {
        (that->*M)();
    }
};
class A
{
public:
    void __stdcall foo()
    {
        std::cout << "hello world" << std::endl;
    }
};
int main()
{
    nested<A, &A::foo> d;
    A t;
    d.call(&t);
}

вот этот код у меня скомпилировал
Цитата

gcc version 3.4.5 (mingw-vista special)

может скомпилятором что-то не так, попробуйте вручную, из командной строки.
Цитата

gcc file_name.cpp -lstdc++



Цитата(vaddsm @  26.5.2009,  22:51 Найти цитируемый пост)
И foo нормально вызывался, хотя не должен бы. 

почему? что ему мешает? попробуйте сгенерировать в уме тот код который сгенерирует компилятор для вашего шаблона, сразу станет понятно почему он работает.
PM   Вверх
vaddsm
Дата 26.5.2009, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



Цитата

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


По вполне, на мой взгляд, понятным причинам. Так как в нутри шаблона необходимо знать не только количество, типы параметров, возвращаяемое значение, но и то каким образом надо работать со стеком. В VS9.0 например такой вот шаблон template <class C, void (C::*M)()> вабще не примет __stdcall метод. Если не указывать явным образом соглашение, должно использоваться соглашение по умолчанию, в борланд в частности для void foo(); это __cdecl. 

Буду рад оказаться не правым ).

В Dev я наблюдаю несколько компиляторов mingw32-gcc.exe и gcc.exe. Сейчас проясню этот вопрос...

Добавлено через 10 минут и 16 секунд
bin>gcc -dumpversion
3.2

bin>gcc main2.cpp -lstdc++
main2.cpp:76: parse error before `)' token
...

bin>
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(vaddsm @  26.5.2009,  23:16 Найти цитируемый пост)

По вполне, на мой взгляд, понятным причинам. Так как в нутри шаблона необходимо знать не только количество, типы параметров, возвращаяемое значение, но и то каким образом надо работать со стеком. В VS9.0 например такой вот шаблон template <class C, void (C::*M)()> вабще не примет __stdcall метод. Если не указывать явным образом соглашение, должно использоваться соглашение по умолчанию, в борланд в частности для void foo(); это __cdecl. 

речь идет про __fastcall я так понял?

ну тут вы видимо ожидаете рантайм ошибки..так? потому что с точки зрения компилятора - все верно. У него через шаблоны передана функция - он ее вызывает. Единственное в чем он виноват - так в том что не выдал ошибку тут
Цитата

nested<A, &A::foo> n;

но...

по стандарту - нет ни __fastcall ни __stdcall. Это дополнения - которые к тому же не являются частью сигнатуры функции. Т.е. GCC не обязан проверять это.
Тогда вопрос - как же это не вылетает рантайм
Цитата

The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible. The following list shows the implementation of this calling convention.

предполагаю что в данный момент это было not possible smile 
PM   Вверх
vaddsm
Дата 26.5.2009, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



без __stdcall в шаблоне идет опять таки нормально
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата

main2.cpp:76: parse error before `)' token

Листинг посмотреть можно?
76 строка, это явно не мой код smile тут есть изменения.
PM   Вверх
vaddsm
Дата 26.5.2009, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 128
Регистрация: 30.6.2007

Репутация: нет
Всего: нет



ВОТ ВОТ!!!! Я о том и твержу. Access violation быть просто обязан. Указал я __fastcall, чтобы нарочито заставить его обломаться, в том случае если он по умолчанию использует передачу параметров через стек а не регистры.

Загадки во тьме.....
PM MAIL   Вверх
azesmcar
Дата 26.5.2009, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 6
Всего: 211



Цитата(vaddsm @  26.5.2009,  23:33 Найти цитируемый пост)
ВОТ ВОТ!!!! Я о том и твержу. Access violation быть просто обязан. Указал я __fastcall, чтобы нарочито заставить его обломаться, в том случае если он по умолчанию использует передачу параметров через стек а не регистры.

Загадки во тьме..... 

__fastcall 100% гарантии что параметры будут помещены в стек - не дает smile 
PM   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0558 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.