J0E То, что VC++ компилит ill-formed код - IMHO, это скорее фича в данном случае. Расширение компилятора. Это характерно для каждого неакадемического компилятора, GCC в этом плане ничем не лучше. Хотя да, могут быть проблемы с кодом, который полагается на это ограничение Стандарта (например, для SFINAE). А в чём состоит баг Comeau? Правильно делает, что не компилит. Разрешено. Точнее явно не запрещено, AFAIK. Такой код Код (Text): struct S { function t; }; Comeau компилит.
"If a declaration ... to have function type..." В первом посте происходит определение (и объявление) указателя, и его типом является никак не "function type".
Явно разрешено (8.3.5/7): Код (Text): typedef void F(); struct A { F foo; }; void A::foo() {} //... template<class> struct B { F bar; }; template<class T> void B<T>::bar() {}
В не шаблонных выражениях зависимый от аргумента шаблонна тип не может быть ни разрешен, ни запрещен, его там и быть не может ) 8.3.5/7 говорит о "A typedef of function type". Твои же слова: " 'F' имеет тип 'void(void)' или просто 'void()' - это так называемый 'function type'". Указателя, не указателя, какая разница, или мы по разному понимаем "a declaration acquires a function type"? Почему же ты считаешь, что тебе обязаны отвечать на вопросы, когда ты сам игнорируешь других? Конкретный пример был показан в #34, Комо ловит ошибку только в одном из определений.
Вольный перевод стандарта: 14.3.1 Аргументы шаблона - типы 3 Если в объявление вовлечен функциональный тип, _зависимый_ от параметра шаблона, и это проводит к объявлению (имеющему функциональный тип), которое не использует синтаксис объявления функции, программа не корректна. Декларация функция описана в 8.3.5 и включает в себя указатели на функции, в том числе и члены.
Не теряй контекст. Чем здесь является 'function': Код (Text): struct S { function t; }; ? Как это какая разница? есть 'function type', есть 'pointer type', декларации соответственно будут называться 'function declaration' и 'object declaration'. (в примере выше - S::t - не объект). 14.3.1/3 к исходному примеру не имеет отношения, 'F' принимает участие в объявлении (и определении) указателя.
Так же как в коде, который привел green (я ему отвечал). А вот в контексте обсуждения несколько раз была упомянута конструкция 'typedef int function();'. Кроме того у меня в ответе в качестве примера явно используется 'typedef void F();'.
Указателя на что? На функциональный тип. Тебя не удивляет что они описаны в стандарте не в 8.3.1 Pointers, а в 8.3.5/9 In the declarator (*pif)(const char*, const char*), the extra parentheses are necessary to indicate that indirection through a pointer to a function yields a function, which is then called. Имеем объявление, в которое вовлечен функциональный тип, но это не выглядит как объявление с вовлечением функционального типа. ЗЫ указатель не определяется, а объявляется с инициализацией.
Я ее и привел, как пример ill-formed Код (Text): template<class T> struct S { T t; }; template<class T> void f(){ T t; } typedef int function(); S<function> a; int main() { f<function>(); }
В контексте последнего struct S { function t; }; не в тему. В последнем случае function не зависит от параметра шаблона, не надо уходить в с торону.
Во первых: 8.3.5/9 не является нормативным, т.к. содержит только примеры (помеченные как [Example:...]). Во вторых: обявления указателей описаны именно в 8.3.1, обявления указателей на члены - в 8.3.3. Берем тот самый злополучный пример: Код (Text): template <class T, class F> void check(F T::*) { F* ptr = &helper; } 8.3.1/1 'F* ptr' ==> T = 'F', D = '* ptr' Тип идентификатора 'ptr' представляет собой указатель на 'F'. Это object declaration, посмотри в 7/5 - там проводится четкое разграничение между 'function declaration' и 'object declaration'. Только вот тип 'ptr' относится к 'object type', а не 'function type', о котором идет речь в 14.3.1/3. В этом примере инициализация не влияет на объявление/определение. Здесь объявление совмещено с определением.
Вот он, контекст: Про независимость от параметров шаблона первый сказал как раз ты Я только привел ссылку на стандарт, в которой проясняется этот момент.
Нешаблоны - не интересны, это не по теме. pointer to T тоже не по теме, не подменяй понятия. Тема о фукциональных типах, которые зависят от аргумента шаблона, и используются в объявлениях содержащих функциональный тип. Пусть там будет хоть 20 поитеров, это не меняет картины. Применяя 7/5 ты хочешь показать, что объявив функциональный тип через typedef, а потом используя typedef для объявления объекта-поинтера (что семантически то же самое) можно легально обойти запрет стандарта? Можно привести альтернативное толкование 4.3.1/3, а не искать опровержения в других?
А это что - 'F* ptr' ? Кардинально меняет. Ну нет в исходном примере выделенного. Есть объявление(определение) которое имеет 'object type'. Ты еще скажи что так нельзя: Код (Text): template<class> struct A{}; template<class T> void f() { A<void(T)> x; } int main() { f<int>(); } Применяя 7/5 я показал ровно то, что стандарт четко различает 'object declaration' и 'function declaration', не больше, не меньше. Твое подходит. Просто ты не видишь разницу между "имеющему функциональный тип" и имеющему 'object type'. Указатель в принципе не может иметь функциональный тип. По ссылке http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29927 обсуждают другой пример. Там действительно пытаются объявить функцию (а не указатель).
J0E Сорри, я невнимательно смотрел код суслика. Теперь вижу, что ты подразумевал под багом в Comeau - то что он компилит код Код (Text): template<class T> void f(){ T t; } typedef int function(); int main() { f<function>(); } который ill-formed согласно Действительно, похоже баг... Хотя в данном случае логичнее было бы поправить Стандарт, а не Comeau. Если в случае классового шаблона это ограничение ещё можно понять, то для шаблона ф-ции оно, IMHO, совершено лишнее - декларации внутри тела ф-ции никак не отражаются на внешних свойствах ф-ции.
Это подмена понятий. F f, * ptr; // got it? Код (Text): template <class T, class F> void check(F T::*) { typedef F F_t; // ill-formed F_t * ptr = &helper; } this causes a declaration to have both object and function types. > Указатель в принципе не может иметь функциональный тип. ты путаешь значения is & has, "иметь" в твоем предложении было бы is в оригинале. 3.9.2 Compound types 1 — pointers to void or objects or functions (including static members of classes) of a given type, 8.3.1; 2 These methods of constructing types can be applied recursively; restrictions are mentioned in 8.3.1, 8.3.4, 8.3.5, and 8.3.2.