R>>Это вообще не должно компилироваться, т.к. ты пытаешься сделать вызов конструктора до определения класса. Там, где ты написал magicc() видно только форвард объявление класса...
NB>а не при создании первой переменной?
Нет.
Вот смотри ещё 2 аналогичных примера, которые _не_ работают по той же причине:
template<typename type>
struct b {};
template<typename type>
struct d : b<d::inner>
{
typedef type inner;
};
template<typename type>
struct b
{
typedef typename type::inner inner;
};
template<typename type>
struct d : b<d>
{
};
R>"ComeauTest.c", line 15: error: the size of an array must be greater than zero
R> char a[magic<>::val != magic<>::val ? 1 : -1];
R> ^
R>Ошибка ни о чём не говорит. Где и что конкретно не так.
Да что ты? Она говорит о том, что magic<>::val он один и не меняется. Или нет?
R>Аааа... ты про это мне хотел сказать???
Не, я хотел о другом — забавно, я вчера пробовал — и он орал о разыменовании нулевых указателей. Похоже, что это он замечает в relaxed mode.
А вообще, так как всем нам, похоже, одинаково некогда/лень ковыряться в стандарте и искать обоснований тех или иных утверждений, лучше подождать авторитетных мнений: Андрея Тарасевича, Павла Кузнецова, elcste (порядок указания имен произвольный ). Можно спросить на comp.lang.c++.moderated.
Лично для меня очевидно, что поиск имен должен работать всегда одинаково и не зависеть от того, что и сколько раз инстанцировалось.
Of course, the code must be complete enough to compile and link.
Re[6]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, remark, Вы писали:
S>>А почему не зделать так?:
думаю, что в обявлении friend должно быть что-то, что инстанцирует magic<type,-1> (то есть не указатель)
но если friend действительно вводит нужную функцию в глобальное пространство и это корректно, тогда можно и указатель.
S>>
S>>template<typename type = int, int id = sizeof( engine( new magic<type,-1> ) ) >
S>>struct magic {
S>> friend int engine( magic<type,-1> * );
S>> static const int val = id;
S>>};
S>>
R>Повторяешь ошибку Chez'a и Gurtovoy — с указателем функция не будет находится по ADL
да вроде находится.
Re[5]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, remark, Вы писали:
R>>>Это вообще не должно компилироваться, т.к. ты пытаешься сделать вызов конструктора до определения класса. Там, где ты написал magicc() видно только форвард объявление класса...
NB>>а не при создании первой переменной?
R>Нет.
аналогичный пример
template< typename T, typename S> struct test;
template< typename T, typename S = typename test<T,void>::type >
struct test {
typedef int type;
};
int main () {
test<int> x;
}
R>Вот смотри ещё 2 аналогичных примера, которые _не_ работают по той же причине:
не аналогичных. ты тип используешь не в определении default параметра.
Здравствуйте, remark, Вы писали:
R>Априори (без ссылок на стандарт) компилирование 3 самыми популярными и приближенными к стандарту компиляторами чего-то да стоит. По крайней мере того, что бы оппонент представил хотя бы какие-то факты, а не просто фразы, что это типа какая-то там некая давно известная дыра где-то
Ну дыра называется The Barton-Nackman Trick.
Но в этом случае всё происходит изнутри шаблона, всё-таки.
Как именно должны взаимодействовать глобальные функции, объявленные в разных инстанциациях шаблона я в стандарте не нашёл
Может плоъхо искал...
Но в целом, видимо есть, по крайней мере надежда, что стандарт можно и удобно трактовать так, чтобы было счастье. Но будет ли оно --
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Невероятно, но факт! Не константные значения в компайл-т
Здравствуйте, remark, Вы писали:
R>Так же как и всё остальные. R>Нет понятия каких-то "других" функций, есть просто функции и они все равнозначны и одинакого влияют на разрешение перегрузки.
Сутиь проблемы в следующем.
В С++ шаблоны определены очень запутано и непоследовательно. Например, относительно легко написать код, который будет зависеть не только от точки инстанциации шаблона, но ещё и от последовательности этих инстанциаций.
Когда инстанциации связаны между собой, то вроде как всё специфицировано, но вот когда они несвязаны никак, то, АФАИК это не специфицировано.
В принципе это правильно, так как предоставляет довольно полезную свободу авторам компиляторов. Скажем каждый шаблон, с каждым набором параметров хотя бы предсказуемо инстанцируется.
А так, от порядка инстанциации шаблонов в единице трансляции, начнёт зависеть то, что нужно генерить по шаблонам. Это приведёт к проблемам с ODR, например.
Так что, ИМХО и АФАИК это всё-таки особенность реализации шаблонов в используемых тобой компиляторах.
Например, может сломаться на компиляторе, который компилит все шаблоны в одну базу на проект, а потом оттуда их переиспользует, то может и не сработать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, remark, Вы писали:
R>Вот это вообще не понял. R>Да, я просто объявляю нешаблонную функцию, но при этом никакими дырками не пользуюсь. R>Примеры таких объявлений можно увидеть и у Страуструпа, и у Саттера и у др.
Дырка состоит в том, что у инстанцирования шаблонного класса есть побочный эффект -- появляется объявление нешаблонной функции в объемлющем пространстве имён. На что именно влияет это объявление,а на что не влияет -- это вопрос очень тонкий.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Невероятно, но факт! Не константные значения в компай
R>Я серьёзно считаю, что поиск имён зависит от того, что видно в POI.
Мне вот тоже влом думать Я написал простой пример:
template<class>
class A
{
friend void fun(const A<char> *);
};
int main()
{
A<char> * p = 0;
fun(p);
}
Комо находит функцию.
Вижуал — лошит — не находит! Зато, если я добавляю
int main()
{
A<int>a;
A<char> *p = 0;
fun(p);
}
Он уже может найти эту функцию. Так вот ты что, утверждаешь, что такое поведение вижуала правильное???
Кстати, а что за бредовую муру пишет вижуал, если сделать так:
int main()
{
A<char> *p = 0;
fun(p);
A<int>a;
}
??
Of course, the code must be complete enough to compile and link.
Re[3]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Шахтер, Вы писали:
Ш>>Здравствуйте, remark, Вы писали:
R>>>Пришло время очередного ресёрча
Ш>>Хочу влить свою бочку дегтя в эту ложку сахарного сиропа.
Ш>>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг.
R>Какие моменты у тебя вызывают недоверие?
Ш>>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт.
R>Почему?
Потому что нарушаются локальность поведения и принцип однозначности значения шаблона как функции аргументов. Нарушение этих базовых принципов ничем не оправдано.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Лично для меня очевидно, что поиск имен должен работать всегда одинаково и не зависеть от того, что и сколько раз инстанцировалось.
По-моему, тут не всё так просто.
template <class X>
class C
{
friend void doSomething(X &);
}
Здравствуйте, Lorenzo_LAMAS, Вы писали:
R>>Я серьёзно считаю, что поиск имён зависит от того, что видно в POI.
L_L>Мне вот тоже влом думать Я написал простой пример: L_L>
L_L>Он уже может найти эту функцию. Так вот ты что, утверждаешь, что такое поведение вижуала правильное???
14.6.5/2
[q]
As with non-template classes, the names of namespace-scope friend functions of a class template specialization
are not visible during an ordinary lookup unless explicitly declared at namespace scope (11.4).
Such names may be found under the rules for associated classes (3.4.2).131) [Example:
template<typename T> class number {
public:
number(int);
//...friend number gcd(const number& x, const number& y);
//...void g()
{
number<double> a(3), b(4);
//...
a = gcd(a,b); // finds gcd because number<double> is an
// associated class, making gcd visible
// in its namespace (global scope)
b = gcd(3,4); // ill-formed; gcd is not visible
}
—end example]
};
[/q]
Re[2]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, Шахтер, Вы писали:
Ш>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг. Ш>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт. Ш>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.
Больше всего это похоже на нарушение ODR.
Вот простенький пример, делающий то же самое абсолютно без наворотов.
char foo(...);
int const x = sizeof(foo(char(0)));
int foo(int);
int const y = sizeof(foo(char(0)));
double foo(char);
int const z = sizeof(foo(char(0)));
Разница лишь в том, что мы не автоматически, а вручную ввели новые определения. Ну и количество уточнений ограничено тремя: char < int < ...
И если это действительно ODR, то программа ill-formed, а поведение компилятора не определено. Тот факт, что большинство компиляторов пошли одним путём — поздравляю.
Могли и не пойти, кстати.
Если компилятор в точке объявления t1 запоминает все дефолтные параметры, доступные на тот момент, то
— t1 != t2
— typeof(x1) == typeof(x2) == typeof(x3)
А если компилятор полагает, что sequence<> и в африке sequence<>, запоминает, что "вот здесь параметры — дефолтные" и затем разворачивает их по месту использования, то
— t1 эквивалентно t2 (т.е. x4...x6 продолжают серию x1...x3)
— typeof(x1) != typeof(x2) != typeof(x3)
Кстати, от VC<=7.0 можно было ожидать именно такого... Раз уж он шаблоны запоминал как AST без проверок.
А особенно прикольно это будет смотреться, когда шаблон дважды встретится в одном выражении. Который будет какой?
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: Невероятно, но факт! Не константные значения в компай
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Шахтер, Вы писали:
Ш>>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг. Ш>>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт. Ш>>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.
К>Больше всего это похоже на нарушение ODR. К>Вот простенький пример, делающий то же самое абсолютно без наворотов.
К>char foo(...);
К>int const x = sizeof(foo(char(0)));
К>int foo(int);
К>int const y = sizeof(foo(char(0)));
К>double foo(char);
К>int const z = sizeof(foo(char(0)));
К>Разница лишь в том, что мы не автоматически, а вручную ввели новые определения. Ну и количество уточнений ограничено тремя: char < int < ...
а где здесь нарушение ODR?
объявлено 3 разных функции.
К>И если это действительно ODR, то программа ill-formed, а поведение компилятора не определено. Тот факт, что большинство компиляторов пошли одним путём — поздравляю. К>Могли и не пойти, кстати.
ну, порядок инстанцирования вроде более менее определен. собственно, это и ипользуется.
R>>template<typename type>
R>>struct magic
R>>{
R>> friend int engine(type);
R>>};
R>>Сколько это определение шаблонного класса должно _сразу_ вынести функций в глобальное пространство имён? Для всего бесконечного возможного набора типов, которыми когда-либо могут параметризовать этот шаблон? PC>Да именно так, т.е. равнозначно этому (кроме прав доступа)
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Априори (без ссылок на стандарт) компилирование 3 самыми популярными и приближенными к стандарту компиляторами чего-то да стоит. По крайней мере того, что бы оппонент представил хотя бы какие-то факты, а не просто фразы, что это типа какая-то там некая давно известная дыра где-то
E>Ну дыра называется The Barton-Nackman Trick. E>Но в этом случае всё происходит изнутри шаблона, всё-таки. E>Как именно должны взаимодействовать глобальные функции, объявленные в разных инстанциациях шаблона я в стандарте не нашёл E>Может плоъхо искал...
Моё мнение такое, что тут никаких особых правил и не надо — всё работает по общим правилам.
E>Но в целом, видимо есть, по крайней мере надежда, что стандарт можно и удобно трактовать так, чтобы было счастье. Но будет ли оно --
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>Так же как и всё остальные. R>>Нет понятия каких-то "других" функций, есть просто функции и они все равнозначны и одинакого влияют на разрешение перегрузки.
E>Сутиь проблемы в следующем. E>В С++ шаблоны определены очень запутано и непоследовательно. Например, относительно легко написать код, который будет зависеть не только от точки инстанциации шаблона, но ещё и от последовательности этих инстанциаций. E>Когда инстанциации связаны между собой, то вроде как всё специфицировано, но вот когда они несвязаны никак, то, АФАИК это не специфицировано. E>В принципе это правильно, так как предоставляет довольно полезную свободу авторам компиляторов. Скажем каждый шаблон, с каждым набором параметров хотя бы предсказуемо инстанцируется. E>А так, от порядка инстанциации шаблонов в единице трансляции, начнёт зависеть то, что нужно генерить по шаблонам. Это приведёт к проблемам с ODR, например.
Вот к проблемам с ODR тут ничего не приведёт.
По факту у меня получается не более, чем:
magic<0>::val;
magic<1>::val;
magic<2>::val;
Такой код можно и руками написать.
Тут ODR _не_ нарушается, и следовательно привести к нарушению ODR в будущем не может. Смотри, например, мою реализацию определения смещения членов в классе — все классы, которые зависят от magic — просто тоже становятся разными классами (точнее разными специализациями).
E>Так что, ИМХО и АФАИК это всё-таки особенность реализации шаблонов в используемых тобой компиляторах. E>Например, может сломаться на компиляторе, который компилит все шаблоны в одну базу на проект, а потом оттуда их переиспользует, то может и не сработать
Каким образом там это сломается? У меня ODR нигде не нарушается. Хоть в одну базу их клади, хоть нет, неважно.