Поиск:

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


Шустрый
*


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

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



тотже:

Код

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

class nested
{
public:
    void call(C* that)
    {
        (that->*M)();
    }
};

class A
{
public:
    void __stdcall foo()
    {
    }
};

int main(int argc, char *argv[])
{

 nested<A, &A::foo> d;
 A t;
 d.call(&t);

 return 0;
 
}


cmd:

Цитата

D:\Program Files\DEVC\Dev-Cpp\bin>gcc main2.cpp -lstdc++
main2.cpp:1: parse error before `)' token
main2.cpp:13: definition of `class A' inside template parameter list
main2.cpp:16: can't make `foo' into a method -- not in a class
main2.cpp:18: declaration does not declare anything
main2.cpp:21: cannot declare `::main' to be a template
main2.cpp:21: confused by earlier errors, bailing out

D:\Program Files\DEVC\Dev-Cpp\bin>


Простите, а что у вас происходит без указания __stdcall в шаблоне, я могу поинтересоваться?
Нормально компилируется и так и так?

Цитата

__fastcall 100% гарантии...


я целый ряд различных соглашений задавал foo, fastcall часный случай. И все равно работает. 

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


uploading...
****


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

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



vaddsm

Чем дальше - тем лучше smile 
Код

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

void __fastcall f(int q, int v)
{
    std::cout << q << v;
}

typedef void (*f_ptr)(int, int);

int main()
{
    f_ptr p = f; //не компилирует minGW
    p(1, 2);
}

Цитата


test.cpp:13: error: invalid conversion from `void (*)(int, int)' to `void (*)(int, int)'

кажется вам пора обновляться

Добавлено через 2 минуты и 34 секунды
Цитата(vaddsm @  26.5.2009,  23:39 Найти цитируемый пост)
Простите, а что у вас происходит без указания __stdcall в шаблоне, я могу поинтересоваться?
Нормально компилируется и так и так?

Код который вы мне показали в последнем посте с ошибками
Цитата


D:\Program Files\DEVC\Dev-Cpp\bin>gcc main2.cpp -lstdc++
main2.cpp:1: parse error before `)' token
main2.cpp:13: definition of `class A' inside template parameter list
main2.cpp:16: can't make `foo' into a method -- not in a class
main2.cpp:18: declaration does not declare anything
main2.cpp:21: cannot declare `::main' to be a template
main2.cpp:21: confused by earlier errors, bailing out

D:\Program Files\DEVC\Dev-Cpp\bin>



у меня на MinGW прошел без ошибок.

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


Шустрый
*


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

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



Код

#include <windows.h>
#include <iostream>
void __fastcall f(int q, int v)
{
    std::cout << q << v;
}
typedef void (*f_ptr)(int, int);
int main()
{
    f_ptr p = f; //не компилирует minGW
    p(1, 2);
}


Ну да, почему в разетку пальцем лезть низя он понимает, даже у меня smile 

Цитата

у меня на MinGW прошел без ошибок.


Понятно, а тот же код но с таким изменением:
Код

template <class C, void (C::*M)()>
class nested
{
//...


Что говорит?

PM MAIL   Вверх
vaddsm
Дата 27.5.2009, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



И всеже такой формы записи
Код

 template <class C, void (C::*M)()>
,
mingw'у вполне хватает чтобы в шаблоне знать тип соглашения о вызове. Проверил под отладчиком вызов метода foo декларированного с различными соглашениями:

Код

; вызов void __stdcall foo(int, int)

push   $0x2
push   $0x1
pushl  0xfffffffc(%ebp)      // this
call   *0xfffffff8(%ebp)


; вызов void __fastcall foo(int, int)

push   $0x2
mov    $0x1,%edx
mov    0xfffffffc(%ebp),%ecx // this
call   *0xfffffff8(%ebp)

; вызов void __cdecl foo(int, int)

push   $0x2
push   $0x1
pushl  0xfffffffc(%ebp) // this
call   *0xfffffff8(%ebp)



К чему я прихожу: Стандарт не определяет формат описания calling convetions в шаблонах? 


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


uploading...
****


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

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



Цитата(vaddsm @  27.5.2009,  00:43 Найти цитируемый пост)
К чему я прихожу: Стандарт не определяет формат описания calling convetions в шаблонах? 

он вообще не определяет calling convetions. 

я думаю так:
__stdcall чисто микрософтовский кейворд и в GCC это по определению не было. Когда GCC портировали под виндоуз (minGW) __stdcall добавили. Возможно это бага старой версии.

Цитата(vaddsm @  27.5.2009,  00:04 Найти цитируемый пост)
Ну да, почему в разетку пальцем лезть низя он понимает, даже у меня smile 

ну мало ли..я думал там вообще с этим неполадки, если тут проверка работает, то почему не работает с шаблонами?

мое мнение: Хоть стандарт и не определяет поведение программы в таких случаях - при добавлении новых фич производители компиляторов должы добавить их так - чтобы они соответствовали общей структуре и логике ЯП. В конкретном случае логично то что он не позволяет компилироватся данной программе (у меня).

Код

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

void __fastcall f(int q, int v)
{
    std::cout << q << v;
}

typedef void (*f_ptr)(int, int);

template <f_ptr fp>
void foo()
{
    fp(1, 2);
}

int main()
{
    foo<f>();
}

вот еще вариант с шаблонами. 
Цитата

test.cpp: In function `int main()':
test.cpp:19: error: no matching function for call to `foo()'

То что он компилует у вас - видимо просто бага - которую уже давно исправили smile обновите MinGW.

vaddsm

да..и еще..я бы с удовольствием взглянул на ассемблерный код сгенерированный для
Код

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? Загадочный компилятор )
 }; 
};

особенно интересует вот эта часть..
(a.*M)(1, 2);
тут эти два параметра push -ами идут в функцию или mov ecx ..., mov edx?
сам не могу..у меня не компилируется smile  smile 

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


Шустрый
*


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

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



azesmcar, посмотри внимательнее, приведенный мною asm это как раз то о чем ты меня сейчас просишь, для 3х случаев когда 

Код

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


объявлена как __fastcall, __stdcall и __cdecl. Для случая с __fastcall первый параметр идет в edx, второй в стек.

Цитата

__stdcall чисто микрософтовский кейворд 


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

Добавлено через 1 минуту и 41 секунду
упс, прошу прощения за "Ты".

Добавлено через 5 минут и 33 секунды
Код

#include <windows.h>
#include <iostream>
void __fastcall f(int q, int v)
{
    std::cout << q << v;
}
typedef void (*f_ptr)(int, int);
template <f_ptr fp>
void foo()
{
    fp(1, 2);
}
int main()
{
    foo<f>();
}


Приведенный вами пример в 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? Загадочный компилятор )
 }; 
};


Действительно баг.

Добавлено через 6 минут и 48 секунд
Радует что в более поздних версиях его выпрямили.
PM MAIL   Вверх
azesmcar
Дата 27.5.2009, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(vaddsm @  27.5.2009,  09:10 Найти цитируемый пост)
azesmcar, посмотри внимательнее, приведенный мною asm это как раз то о чем ты меня сейчас просишь, для 3х случаев когда 

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


Цитата(vaddsm @  27.5.2009,  09:10 Найти цитируемый пост)

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


Цитата

The following conversions are performed on each expression used as a non-type template-argument. If a
non-type template-argument cannot be converted to the type of the corresponding template-parameter then
the program is ill-formed.

— for a non-type template-parameter of integral or enumeration type, integral promotions (4.5) and integral
conversions (4.7) are applied.

— for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and the
array-to-pointer conversion (4.2) are applied. [Note: In particular, neither the null pointer conversion
(4.10) nor the derived-to-base conversion (4.10) are applied. Although 0 is a valid template-argument
for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type
template-parameter of pointer type. ]

— For a non-type template-parameter of type reference to object, no conversions apply. The type referred
to by the reference may be more cv-qualified than the (otherwise identical) type of the templateargument.
The template-parameter is bound directly to the template-argument, which must be an
lvalue.

— For a non-type template-parameter of type pointer to function, only the function-to-pointer conversion
(4.3) is applied. If the template-argument represents a set of overloaded functions (or a pointer to such),
the matching function is selected from the set (13.4).


— For a non-type template-parameter of type reference to function, no conversions apply. If the
template-argument represents a set of overloaded functions, the matching function is selected from the
set (13.4).

— For a non-type template-parameter of type pointer to member function, no conversions apply. If the
template-argument represents a set of overloaded member functions, the matching member function is
selected from the set (13.4).


— For a non-type template-parameter of type pointer to data member, qualification conversions (4.4) are
applied.


Добавлено @ 09:28
Цитата(vaddsm @  27.5.2009,  09:10 Найти цитируемый пост)
упс, прошу прощения за "Ты".  

да без проблем smile 

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


Шустрый
*


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

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



Для нетипового шаблонного параметра типа указатель на функцию, применяется только “функция к указателю (4.3)” конверсия. Если аргумент шаблона представлен множеством перегруженных функций (или указателем на таковые), то подходящая функция выбирается из множества. 

Для нетипового шаблонного параметра типа указатель на метод, конверсия не применяется. Если аргумент шаблона представлен множеством перегруженных методов (или указателем на таковые), то подходящий метод выбирается из множества. 


Конверсия != Конвенция 

Иными словами в приведенном фрагменте стандарта ничего не говорится о соглашених о вызовах.

Добавлено через 8 минут и 18 секунд
The C++ Standard [ISO/IEC 14882] has very little to say about calling conventions. It has a bit to say about language linkage and linkage specifications, and it notes that a particular language linkage may be associated with a particular calling convention. Everything else related to calling conventions is implementation specific.


Implementation specific для calling conventions, где бы найти  smile  smile ??
PM MAIL   Вверх
azesmcar
Дата 27.5.2009, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(vaddsm @  27.5.2009,  21:30 Найти цитируемый пост)
Иными словами в приведенном фрагменте стандарта ничего не говорится о соглашених о вызовах.

не только в приведенном фрагменте. Этот фрагмент касается non-type template-parameter-ов. smile 
т.е. это то что в стандарте сказано про передачу шаблонному классу/функции нетипового параметра.

Добавлено через 1 минуту и 53 секунды
Цитата(vaddsm @  27.5.2009,  21:30 Найти цитируемый пост)
Implementation specific для calling conventions, где бы найти  smile  smile ?? 

смотря для кого? smile 
если для студии - в MSDN, если для MinGW - то у них на сайте предполагаю что будет.

Добавлено через 4 минуты и 43 секунды
http://www.hackcraft.net/cpp/MSCallingConventions/

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


Шустрый
*


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

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



Тот факт, что стандарт языка не регламентировал «Implementation specific of calling conventions» меня весьма удручает, ну что ж, все же это ответ на вопрос “Почему?”, хоть и отрицательный. 

На последок хочется взять и кинуть огромным булыжником в огород Borland. 

Апеллируя к вашим словам “при добавлении новых фич производители компиляторов должы добавить их так - чтобы они соответствовали общей структуре и логике ЯП”, с которыми я чертовски согласен, замечу: Что, разработчики компилятора Borland либо с нами не согласны либо сильно накасячили, заставив пользователей писать:

Код

template <class R, class T0>
class sometemplate<R __some_calling_convention (*)(T0)>
{
};


вместо волне логичного:

Код

template <class R, class T0>
class sometemplate<R  (__some_calling_convention *)(T0)>
{
};


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


uploading...
****


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

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



vaddsm

надеетесь стать чемпионом по метанию камней в огород борланда? smile тут их каждый день кидают
что я говорю...я же в разделе Borland C++ Builder
но он в самом деле весьма сомнительно поддерживает стандарт, хотя получше чем Visual Studio 6. Но не будем забывать сколько лет дедушке.
PM   Вверх
vaddsm
  Дата 27.5.2009, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 smile еще один фейл Борланда:


Код

  template < typename T, T*(T::*)() > struct ptmf_helper {};
  template < typename T > bool has_user_constructor_helper(...);
  template < typename T > bool has_user_constructor_helper(ptmf_helper<T, &T::Constructor>* p);


Heeelp me!!! )
PM MAIL   Вверх
vaddsm
Дата 28.5.2009, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



boost::enable_if так же не работает на 6.0. Вероятно по причине того что принцип substitution-failure-is-not-an-error в компиляторе не реализован (. Придется мне видимо отказаться от некоторых замечательных вещей ради совместимости. Но если вдруг у кого-то будет идея как заставить последний ряд шаблонов работать на этом компиляторе.... Буду ОЧЕНЬ рад.
PM MAIL   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

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

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

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

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


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

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


 




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


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

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