Нет не верно, ты мог бы засабмитить баг в МС, но учти что придётся их убедить пунктами стандарта, а не "комо это понимает".
J0E Только не "комо", а "камю" (Comeau). "It is widely regarded as the most standards-conformant C++ compiler." - подсказывает нам википедия. Мне пока что не удалось найти в нем хотя бы один баг, а то, что мне казалось багом, оказалось моим незнанием стандарта. Однако, к теме топика это отношения не имеет - баг тут явный, и никакие конкретные пункты стандарта тут не нужны - достаточно сказать что конвенция вызова в стандарте никак не фигурирует, а введенное расширение не должно ломать стандартные конструкции. А про сабмит бага в мс это ты хорошо пошутил, спасибо, посмеялся
Этого никто не делает. Немного изменил: Код (Text): struct A { void foo(int, int){} }; void bar(int, int){} int main() { typedef void F(int, int); F A::* mf = &A::foo; F * pf = &bar; // <- Вот это делают (и это должно работать) } 'F' в любом случае имеет тип 'void(int, int)', который вообще не имет отношения к 'А'.
_DEN_ ты прав камо к теме отношения не имеет, зачем про него оффтопить. но баги в нем находили. Про сабмит в МС я не шутил, делал это сам на connect.microsoft.com заполняешь форму, но надо обосновать, как и любой баг, иначе внимания не обратят и отпишут отговорку. nop_ - спасибо, опять туплю с адресами напутал. Может быть в первом коде и есть какой-то смысл, отличный от №10, но судя по имени check и дальнейшему молчанию ДЭна - он не связан с программированием и С++ в частности.)
Код (Text): template <class T, class F> void check(F T::*) { F* ptr = (F*)&helper; } Воть, VS 2005 конпелирует.
_DEN_ тю, фишка в том, что я ложил болт, кто что тут обо мне думает ) поэтому уже который раз повторю: я не понимаю нах это надо, ты можешь объяснить? где мешает конвенция вызовов. а до тех пор буду троллить твое ЧСВ, может багрепорты научишся в результате писать Booster - это вариант на тему №8, щас Ден нарисует непонятный смайлик и попробуй поиграть c /Gz
J0E Ну так главное, чтобы конпелировалось, шутко ^) А вообще я согласен, что VS сливает, gcc тут полностью солидарен с comeu. Хотя не уверен что это именно баг, а не ub. Так как всё конкретизируется в указатель на мембер.
green откуда основания, где-то можно его скачать? У меня нет вопросов, почему ты называешь багом поведение 2010beta2. Компиль выводит тип шаблона, но потом не может привести к этому типу. Стандарт читать не нужно и так понятно что то тут не то ) Однако по поводу замысла Дэна я бы с радостью послушал комментарии, смотрю стандарт: 14.3.2 Template non-type arguments [temp.arg.nontype] 1 A template-argument for a non-type, non-template template-parameter shall be one of: — an integral constant-expression of integral or enumeration type; or — the name of a non-type template-parameter; or — the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or — a pointer to member expressed as described in 5.3.1 . 2 [Note: A string literal (2.13.4) does not satisfy the requirements of any of these categories and thus is not an acceptable template-argument. [Example: template<class T, char* p> class X { // ... X(); X(const char* q) { /* ... */ } }; X<int,"Studebaker"> x1; // error: string literal as template-argument char p[] = "Vivisectionist"; X<int,p> x2; // OK —end example] —end note] 3 [Note: Addresses of array elements and names or addresses of non-static class members are not acceptable template-arguments. [Example: template<int* p> class X { }; int a[10]; struct S { int m; static int s; } s; X<&a[2]> x3; // error: address of array element X<&s.m> x4; // error: address of non-static member X<&s.s> x5; // error: &S::s must be used X<&S::s> x6; // OK: address of static member —end example] —end note]
Замечание относится к варианту №3. Если это верно то почему компилятор должен выводить типы в первом варианте?
Лан, посмеялись и хватит баттхерт, как выражается Дэн, или тяга к знаниям, как скажу я не дает мне спокойно ждать завтра template<class T> struct S { T t; }; template<class T> void f(){ T t; } typedef int function(); S<function> a; int main() { f<function>(); } Видно суслика? Или я теперь уже действительно туплю? )))
J0E Я не поленился запостить этот баг в MS Connect - регрессия относительно 2008, однако. Вот в такой форме: Код (Text): struct foo { void bar() {} }; template <class T> void check(T foo::*) { } void test() { check(&foo::bar); } Сказали, что пофиксено уже. В данном случае параметр шаблона - именно тип. Общая идея кода _DEN_ и RedLord состоит в том, чтобы из сложного типа "указатель на член структуры" выделить тип, определяющий свойства члена безотносительно его принадлежности к структуре. Так, в struct foo { int m_; int f(); }; искомый тип для типа указателя на m_ (т.е. int foo::*) будет int, а для типа указателя на f (т.е. int (foo::*)()) - int (*)(). В общем случае, нужно из типа 'T foo::*' получить тип T. Для реализации этой идеи _DEN_ использовал выведение типа в функциональных шаблонах, а RedLord - частичную специализацию в классовых шаблонах. В принципе, должны работать оба метода, но оказывается, что второй(частичная специализация) в VC++ реализован лучше. Точнее говоря, RedLord тоже использует выведение, но только для предварительного получения полного исходного типа. Что касается соотношения конвенций вызова в T и "T foo::*", то в случае VC++ видно, что компилятор для ф-ции-члена с дефолтной конвенцией (__thiscall) выводит дефолтную конвенцию (определяемую настройками компилятора) для соответствующего типа свободной ф-ции, таким образом обеспечивая корректную компиляцию стандарт-совместимого кода.
green вообще конечно жалко, что ты ответил раньше Дэна. с моей стороны будет грубостью рассчитывать на твои экстрасенсорные чувства, учитывая твои развернутые ответы, ты не ждешь от людей, что будут тратить свое время на понимание тебя. Вот откуда код с сусликом: 14.3.1 Template type arguments 3 If a declaration acquires a function type through a type dependent on a template-parameter and this causes a declaration that does not use the syntactic form of a function declarator to have function type, the program is ill-formed. [Example: template<class T> struct A { static T t; }; typedef int function(); A<function> a; // ill-formed: would declare A<function>::t // as a static member function —end example]
J0E Про суслика, я что-то не пойму, каким боком это сюда относится... Или не относится? А вообще, интересно... я не знал про этот пункт Стандарта. IMHO, довольно странно, что запрещается нефункциональная форма декларации ф-ции в шаблонных структурах. Ведь в обычных(нешаблонных) структурах она разрешена. Непоследовательно как-то... Или они испугались слишком большого семантического разброса в разных инстанциациях шаблона, или посчитали слишком сложным анализ такого шаблона компилятором... Скорее всего и то, и как следствие, другое.
Суслик это похоже баг в Комяу, который Дэн нашел, сам того не подозревая. Комяу компилирует половину этого примера, а ВЦ полностью, как и ill-formed example из 14.3.1/3. Но я не уверен что следует этот баг сабмитить, в Бусте припоминаю где-то в комментах к function либо typeof про использование багофич. В не шаблонных выражениях такое не разрешено то же, поскольку там нет типов, зависимых от параметров шаблона. Или имеются ввиду варианты типа: template<class T> S { struct inner { T t; }; }; но по-моему здесь тип тоже зависим.
А почему не должно относиться к первому посту? Декларация есть, функциональный тип зависит от параметров шаблона. Синтаксис отличен от определения функционального типа (нет скобочек). Поэтому мне кажется что если нужны какие то определения, то типы для них следует выводить как в №12, разбирая подробно.