Как добавить в форму (класс) новое свойство нестандартного типа?
как добавить в форму (класс) новое свойство нестандартного типа, например мне нужно добавить новое свойство типа regex из библиотеки Boost.Regex. (Библиотеку к проекту я подключил :)
по идее должно быть:
__property regex Expression = { read = <имя>, write = <имя> };
для чего нужны атрибуты свойства, и что там нужно указать?
Буду благодарен за ссылку на доку где это описывается. Заранее спасибо!
Подскажите пожалуйста чайнику, день потратил - не нашел ответа...
как добавить в форму (класс) новое свойство нестандартного типа, например мне нужно добавить новое свойство типа regex из библиотеки Boost.Regex. (Библиотеку к проекту я подключил :)
по идее должно быть:
__property regex Expression = { read = <имя>, write = <имя> };
для чего нужны атрибуты свойства, и что там нужно указать?
Буду благодарен за ссылку на доку где это описывается. Заранее спасибо!
Насколько я понял вопрос, интересуют те самые <имена>, которые read и write?
[COLOR=darkblue]read = <имя>[/COLOR] -- это имя функции, которая будет выполняться, при обработке конструкции <переменная> = <объект>->regex;. Функция дожна, вестимо, иметь тот же тип, что и свойство regex.
[COLOR=darkblue]write = <имя>[/COLOR] -- имя функции, которая будет выполняться в конструкции <объект>->regex = <выражение>;, в ней мы должны обеспечить сохранение значения, присвоенного свойству regex.
В моём случае в библиотеке regex имеются специальные структуры (с методами) для работы с regex, и передавать/получать что то в/от regex мне не надо.
А в кострукции <переменная> = <объект>->regex; у меня <объект>'ом является главное окно приложения...
Можно ли не испльзовать (обойти) эти атрибуты read и write?
Например в VC++ просто:
[COLOR=darkblue]
class CDwl2mysqlApp : public CWinApp
regex Expression;
[/COLOR]
В моём случае в библиотеке regex имеются специальные структуры (с методами) для работы с regex, и передавать/получать что то в/от regex мне не надо.
regex - это класс, библиотека - Boost
А в кострукции <переменная> = <объект>->regex; у меня <объект>'ом является главное окно приложения...
Можно ли не испльзовать (обойти) эти атрибуты read и write?
Ну так вызывай методы напрямую, что, кстати, правильнее, чем использовать "атрибуты".
Например в VC++ просто:
[COLOR=darkblue]
class CDwl2mysqlApp : public CWinApp
regex Expression;
[/COLOR]
Извини, но пример ставит под сомнение твою компетентность в С++.
regex - это класс, библиотека - Boost
Ну так вызывай методы напрямую, что, кстати, правильнее, чем использовать "атрибуты".
Извини, но пример ставит под сомнение твою компетентность в С++.
Рискую показать свою некомпетентность, но я предпочитаю (речь не о групповом проекте, ясное дело) в своих сиротских прогах делать переменные в Public, ежели нужда их изменять...
Рискую показать свою некомпетентность, но я предпочитаю (речь не о групповом проекте, ясное дело) в своих сиротских прогах делать переменные в Public, ежели нужда их изменять...
Тогда запись должна выглядеть вот так, на сколько я полагаю:
{
public:
regex Expression;
};
aka BioUnit
regex - это класс, библиотека - Boost
Что невероятно, Boost это действительно библиотека! А если ознакомиться с ней, то она делится на множество разных библиотек (смотри сюда сюда)
и том списке есть library Boost.Regex
Если вдаваться в детали, regex (компонента этой library) раньше была классом, затем её автор (из соображений устойчивости кода) переписал в структуру.
Так что еще одна ошибка, а вот и нет, regex - это не класс, почитай доку в разделе Boost.Regex...
Ну так вызывай методы напрямую, что, кстати, правильнее, чем использовать "атрибуты".
Я хотел спросить, другими словами, как добавить свойство в мастере добавления свойств,(использование мастера в начале освоения Buider'a избавит начинающего от многих ошибок)и что указать мастеру в пункте reads и writes?
Извини, но пример ставит под сомнение твою компетентность в С++.
Смешной ты, Drew. Так и быть, извиняю. Столько флейма из-за невнимательности...
Смотри сюда:
Подскажите пожалуйста чайнику...
2 Drew
Думаю что ты совсем не рискуешь :-)
Если вдаваться в детали, regex (компонента этой library) раньше была классом, затем её автор (из соображений устойчивости кода) переписал в структуру.
Так что еще одна ошибка, а вот и нет, regex - это не класс, почитай доку в разделе Boost.Regex...
Я увидел совершенно обратное:
namespace boost{
template <class charT,
class traits = regex_traits<charT>,
class Allocator = std::allocator<charT> >
class basic_regex;
typedef basic_regex<char> regex;
typedef basic_regex<wchar_t> wregex;
}
Но хорошо, соглашусь, но только в том случа, если укажешь отличие класса от структуры.
Я хотел спросить, другими словами, как добавить свойство в мастере добавления свойств,(использование мастера в начале освоения Buider'a избавит начинающего от многих ошибок)и что указать мастеру в пункте reads и writes?
Наверное, так и надо было спрашивать.
Думаю, ничего страшного не будет, если обойтись без мастера.
Подробно можно посмотреть здесь:
http://www.codenet.ru/progr/bcb/rtti.php
Хочу лишь заметить, что свойство - это не реально существующий объект, а скорее способ доступа.
P.S. И все же мне не понятно, зачем использовать такие извращения, доставшиеся Билдеру в наследство от Object Pascal, не свойственные языку С++. Почему бы просто не использовать методы для доступа к объекту regex.
Если вдаваться в детали, regex (компонента этой library) раньше была классом, затем её автор (из соображений устойчивости кода) переписал в структуру.
Так что еще одна ошибка, а вот и нет, regex - это не класс, почитай доку в разделе Boost.Regex...
Пардон, :{ беру свои слова обратно, спутал с другой библиотекой, вот этой - GRETA Regular Expression, см. пункт Notice to Users of Version 1.x:
"Most notably, the regexpr object has gone away..."
P.S. И все же мне не понятно, зачем использовать такие извращения, доставшиеся Билдеру в наследство от Object Pascal, не свойственные языку С++. Почему бы просто не использовать методы для доступа к объекту regex.
Меня тоже мучает этот вопрос, зачем мне использовать эти {read,write}? Как их обойти при ипользовании мастера? Обойтись без мастера не получается :(. "Просто использовать методы доступа" - до этого дело не доходит, мастерства не хватает, если пишу вручную:
#include <boost/regex.hpp>
...
...
class TForm1 : public TForm
{
...
...
regex Expression; // Здесь возникает ошибка!
Спасибо за ссылку, попробую разобраться.
Но хорошо, соглашусь, но только в том случа, если укажешь отличие класса от структуры.
Найди отличия...
Первое - доступ к членам по умолчанию:
class - private
struct - public
Хочу лишь заметить, что свойство - это не реально существующий объект, а скорее способ доступа.
Бред. Св-во = поле + методы записи/чтения...
И все же мне не понятно, зачем использовать такие извращения, доставшиеся Билдеру в наследство от Object Pascal, не свойственные языку С++. Почему бы просто не использовать методы для доступа к объекту regex.
Это не извращения, это расширение языка. Извращение это #import, #pragma data_seg и т.д.
Потому, что это удобней сравнить: Object.myregex = value;
и Object.myregex->SetValue(Value);
Даже MS в своей новой лаже С# активно это использует.
- А откуда идут "извращения"?
- Надо спросить у главного идиолога С#/.NET - Хелсберга (в прошлом разработчика Object Pascal/Delphi)
Человеку всего навсего нужно было ответить след:
Вызови ClassExplorer
Выбери создать новое св-во
В поле Name введи Fmyregex
В поле Type введи Boost::Regex
Поставь галку Создать поле
Поставь галки Использовать поле для чтения/записи
Нажми Ок. Пролучится:
{
__published: // IDE-managed Components
private:
Boost::Regex Fmyregex;
public:
__property Boost::Regex myregex = { read=Fmyregex, write=Fmyregex }; // User declarations
};
Билдер рулит!
Найди отличия...
Первое - доступ к членам по умолчанию:
class - private
struct - public
АГРОМНОЕ спасибо!
Только вот спрашивал я не у тебя, но раз уж ты решил отвечать за других, то ответь в чем разница между ними в данном контексте:
Если вдаваться в детали, regex раньше была классом, затем её автор (из соображений устойчивости кода) переписал в структуру.
Так что еще одна ошибка, а вот и нет, regex - это не класс.
Бред. Св-во = поле + методы записи/чтения...
{
__published: // IDE-managed Components
private:
Boost::Regex Fmyregex;
public:
__property Boost::Regex myregex = { read=Fmyregex, write=Fmyregex }; // User declarations
};
Тогда не понятно, зачем в твоем примере два поля одинакового типа?
Какой будет размер экземпляра класса TForm1?
sizeof(TForm1) = sizeof(TForm) + 2* sizeof(Boost::Regex)
так?
Это не извращения, это расширение языка.
Извращение это #import, #pragma data_seg и т.д.
Потому, что это удобней сравнить: Object.myregex = value;
и Object.myregex->SetValue(Value);
Извращение это введено было лишь для того, чтоб подогнать VCL под C++.
Свойства (property) введены в Builder C++ специально для поддержки классов, описанных на Object Pascal.
А чего же удобного в Object.myregex?
Это противоречит концепции С++: не понятно же становится объект это или что-то другое...
Кстати, а как ведет себя это поле в шаблонных функциях, при взятии адреса (&Object.myregex) и др. операции, которые возможно с обычными объектами?
Даже MS в своей новой лаже С# активно это использует.
- А откуда идут "извращения"?
- Надо спросить у главного идиолога С#/.NET - Хелсберга (в прошлом разработчика Object Pascal/Delphi)
Да мне пох, что что MS использует в C#.
Я пишу на С++, чего и вам желаю.
А у Хелсберга (в прошлом разработчика Object Pascal/Delphi) неплохо бы спросить, понимает ли он назначение деструкторов. :)
Меня тоже мучает этот вопрос, зачем мне использовать эти {read,write}? Как их обойти при ипользовании мастера? Обойтись без мастера не получается :(. "Просто использовать методы доступа" - до этого дело не доходит, мастерства не хватает, если пишу вручную:
#include <boost/regex.hpp>
...
...
class TForm1 : public TForm
{
...
...
regex Expression; // Здесь возникает ошибка!
Так может проблема не в {read,write}, а вчем то другом. Что за ошибка то?
Возникает в определении класса или же при доступе к его членам?
Спасибо за последовательность шагов для решения проблемы.
К сожалению напишу немного offtopik'а...
Прошу не принимать заявленное здесь близко к сердцу, я конечно понимаю, что любимая среда программирования - это почти как религия, и собеседник, выражая свое мнение, легко может оскорбить "чувства верующего".
Просто я, скажем поклонник g++ (или чего-то другого, "неBuilder'а"), привык видеть конструкцию (участок кода) вот таким, и если что-то в нём не так, у меня возникает естественное чувство недоумения, которое я и высказываю, но это выражается вовсе не с целью задеть кого-либо.
Ошибка во время компиляции.
К сожалению сейчас я на работе,а проект у меня на домашнем компьютере, сейчас точно не вспомню что за ошибка, боюсь ошибиться.
Пойду домой - посмотрю.
#include <boost/regex.hpp>
...
...
class TForm1 : public TForm
{
...
...
regex Expression; // Здесь возникает ошибка!
Похоже на то, что regex-а не имеет конструктора с пустым списком инициализации.
Похоже на то, что regex-а не имеет конструктора с пустым списком инициализации.
Вроде бы есть, если по документации смотреть:
этот должен прокатить за конструктор без параметров.
Можно попробовать вызвать конструктор с параметрами для regex Expression;
:Expression(arg1,arg2,...,argn) // где arg -аргументы
{
}
Может, компилятор Борланда не может проглатить эту реализацию regex? Ты используешь какую-то портированную под этот компилятор версию? У него (у компилятора Борланда) множество проблем с шаблонами.
Может, компилятор Борланда не может проглатить эту реализацию regex? Ты используешь какую-то портированную под этот компилятор версию? У него (у компилятора Борланда) множество проблем с шаблонами.
Крутой спец. по STL говорил, что лучшая реализация STL, это у CBuilder(5). Но это он сказал после того, как мы натолкнулись на один баг. :)
Я не использую boost.
Просто, если не ошибаюсь конечно,
regex Expression;
может не проходить по 2 причинам.
компилятор не находит класс regex или же все его конструкторы с аргументами.
Так может проблема не в {read,write}, а вчем то другом. Что за ошибка то?
Вот эта ошибка, вернее она первая в списке:
(C++ Error) main.h(32): E2303 Type name expected
за ней в списке следует такая:
(C++ Error) main.h(32): E2139 Declaration missing ;
Может, компилятор Борланда не может проглатить эту реализацию regex? Ты используешь какую-то портированную под этот компилятор версию?
Нет, версия 1.31.0, сходил на сайт, там на download странице нет разделения на поддерживаемые компиляторы, Одна версия на >4 компилятора. Благодаря твоему вопросу увидел и скачал, затем установил патч :). Но это не помогло - та же ошибка... :(
Чтобы не морочить вам голову, расскажу подробнее. Использую Builder 6 под Win XP.
Библиотека установлена правильно и работает, вот этот пример из доки в пробной программке работает замечательно, если в пределах одной функции TMainForm::Button1Click (чтобы обойти проблему области видимости Expression) даю строку:
regex Expression("^([0-9]+)(\\-| |$)(.*)$");
и вызов использующей функции:
if(regex_match( in.c_str(), what, Expression))
Всё работает замечательно.
Но вот в таком примере появляется ошибка, извините, приведу весь листинг:
#ifndef mainH
#define mainH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <string>
// ---- Добавлено из примера ----
#include <cstdlib>
#include <stdlib.h>
#include <boost/regex.hpp>
//#include <iostream> -----------
class TMainForm : public TForm
{
__published:
TMemo *Memo;
TButton *Button1;
TButton *OptButn;
TProgressBar *ProgressBar;
void __fastcall Button1Click(TObject *Sender);
void __fastcall OptButnClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
public:
__fastcall TMainForm(TComponent* Owner);
void progress_ftp(const char* response, std::string* msg);
regex Expression; // Здесь 1-я и 2-я ОШИБКИ
// __property regex Expression;
};
extern PACKAGE TMainForm *MainForm;
#endif
Файл main.cpp
#include <vcl.h>
#pragma hdrstop
#include "main.h"
#include "Options.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
// ---- Добавлено из примера ----
using namespace std;
using namespace boost;
// -------------------
TMainForm *MainForm;
__fastcall TMainForm::TMainForm(TComponent* Owner): TForm(Owner)
{
}
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
regex Expression("^([0-9]+)(\\-| |$)(.*)$");
std::string in, out;
in = "100 this is an ftp message text"; // Для отладки
this->progress_ftp(in.c_str(), &out);
if(out.c_str() != "" ) // ?
{
Memo->Lines->Add("Match found");
Memo->Lines->Add("Message text: ");
Memo->Lines->Add(out.c_str());
}
else
{
Memo->Lines->Add("Match not found");
}
}
void __fastcall TMainForm::OptButnClick(TObject *Sender)
{
OptForm = new TOptForm(this);
if (OptForm->ShowModal()==mrCancel) return;
// ...
}
}
void __fastcall TMainForm::FormCreate(TObject *Sender)
{
}
TMainForm::progress_ftp(const char* response, std::string* msg)
{
cmatch what;
if(regex_match(response, what, Expression))
{
// what[3] contains the text message.
if(msg)
msg->assign(what[3].first, what[3].second);
}
if(msg) // failure did not match
msg->erase();
}
Крутой спец. по STL говорил, что лучшая реализация STL, это у CBuilder(5). Но это он сказал после того, как мы натолкнулись на один баг. :)
На сколько я знаю и у Borland и у VC++ одна реализация STL. Если интересно, могу поднять инф. о том, кто её писал.
На данный момент лучшая IMHO (и не только IMHO) реализация - это STLPort (http://stlport.com).
Я вот только не пойму причем тут STL и моё заявление с проблемами Borland-ского компилятора с шаблонами?
Вы не согласны, что Borland не дружит с шаблонами?
Могу доказать. И успокойтесь, ярые поклонники Borland, у VC++ тоже есть проблемы с шаблонами, но у него дела все же по-лучше, чем у Borland.
Но вот в таком примере появляется ошибка, извините, приведу весь листинг:
При беглом просмотре заметил, что ты не указываешь область видимости для boost.
В примере есть строчка
using namespace boost;
у тебя её нет (в .h), а она как раз отвечает за область видимости. Я противник using namespace, поэтому рекомендую писать так:
boost::regex Expression;
Именно по этому все работает в TMainForm::Button1Click.
Далее я бы избавился от __property в определении Expression в классе TMainForm. Давайте привыкать (или не отвыкать) от хорошего стиля программирования на С++.
Кстати, опять же для хорошего стиля я бы отказался от
using namespace std;
using namespace boost;
указывая область видимости каждый раз, где это над. Для std::string ты это уже делаешь.
Ну и не стоит указывать this, там где это совсем не надо, например здесь
this->progress_ftp(in.c_str(), &out);
можно просто
progress_ftp(in.c_str(), &out);
Особенно, что это был ответ на мой вопрос: "Если баг из борландовской STL мы убрать не сможем, может перепишу все это на Visual C?"
Поставь STLPort (stlport.com) и не парься.
Кстати, иногда бывают "баги" по вине программиста, когда последний забывает, что STL не потокобезопасная библиотека по стандарту.
1. Чтоб использовать STL, шаблоны, классы: нужна такая задача. Напр. бухгалтерские программы на это не тянут.
Все зависит от архитектуры. У нас, к примеру, есть проект сетевого фаерволла (R-Firewall), там мы в полную силу используем и STL, и Boost, и WTL, и собственные шаблонные библиотеки классов (а-ля Александреску).
2. STL имеет свои ограничения, в первую очередь в быстродействии. Я теперь работаю над одном Windows/Web сервисе, несколько сот тысяч записей (ближе к миллиону) Хоть там такие структуры, что трудно им имя дать, но и мысли не имел использовать STL. Хотя бы потому, что они очень долго заполняются.
Х-м... опять же все зависит от правильности использования.
К примеру, другой наш проект, система разграничения прав доступа к файлам (R-Guard, data-security-software.com) использует модифицированный STL в драйверах файловых систем. Модификация коснулать потокобезопасности и скорости работы. Переписали отдельные части так, что теперь они работают даже на многопроцессорном железе в кольце 0.
3. Это относится к топику "Организация обучения". Там вы спорили, об ООП и структурном программировании.
Вчера на одном иностранном сайте читал об одной задаче: есть слово длиной 10-20 кБ. Определить минимальное число символов, которых нужно вычеркнуть из этого слова, чтоб получить слово, который читается справа и слева одинаково. Было несколько решений(68 ответов 4 или 5 алгоритмов), но мне кажется, что ни одна задачу не решала.(Если не ошибаюсь, то это pN-полная задача.) Green,IYHO, если допустим книгу Андрея Александреску: "Современное проектирование на C++" человек выучит наизусть, то это уже гарантия того, что он сможет решить эту задачу? Там решением принимался, алгоритм, который быстрее всего удалит ненужные символы.
Я не понял, это вопрос или наезд? :D
Вообще-то, пора уже завести отделную ветку.
Шаблоны - это конечно не панацея от всех бед. Введены шаблоны были для повышения абстракции языка. А в данном случае задача ставится конкретная. Вот если бы задача стояла так: создать что-то, что может в массив однородных элементов, а может и не массив, а может и не однородных, добавлять или удалять или производить еще какие то действия с эти неизвестно что. Как в мультфильме: "...на ель она взлетела, а может не взлетела, а может быть на пальму с разбегу взобралась..."
Еще одной особенностью шаблонов является то, что они инстанируются в процессе компиляции. Это можно использовать в некоторых фокусах а-ля Александреску. Тогда в принципе книга Александреску могла бы помочь в реализации решения этой проблемы, например, если строка должна была бы быть преобразована не в run-time, а в compile-time. Есть правда одна проблема: классы имеют некоторые проблемы с массивами, а шаблонные классы их имеют еще больше. Например, нет способа (если кто знает, поделетесь) инициализировать константный массив в конструкторе класса, как это делается с обычными константами:
struct A
{
const int val;
A() :val(5) {}
};
При беглом просмотре заметил, что ты не указываешь область видимости для boost.
В примере есть строчка
using namespace boost;
у тебя её нет (в .h), а она как раз отвечает за область видимости.
Я противник using namespace,
Просмотрел regex.h, там имеется строка:
#include <boost/cregex.hpp>
а в cregex.hpp есть строка:
#include <boost/regex/config.hpp>
в котором в свою очередь нашёл:
namespace boost{ namespace re_detail{
#ifdef BOOST_NO_STD_DISTANCE
template <class T>
std::ptrdiff_t distance(const T& x, const T& y)
{ return y - x; }
#else
using std::distance;
#endif
}}
поэтому рекомендую писать так:
boost::regex Expression;
Именно по этому все работает в TMainForm::Button1Click.
Попробую.
Далее я бы избавился от __property в определении Expression в классе TMainForm.
Это я пробовал варианты, эта строка-ремарка.
Спасибо за ответы! у меня появились дополнительные вопросы для изучения, не буду здесь их задавать, наглеть :roll:, да и когда доку не просто читаешь, а ишешь ответы, тогда понимать материал гораздо легче :)
Х-м... опять же все зависит от правильности использования.
К примеру, другой наш проект, система разграничения прав доступа к файлам (R-Guard, data-security-software.com) использует модифицированный STL в драйверах файловых систем. Модификация коснулать потокобезопасности и скорости работы. Переписали отдельные части так, что теперь они работают даже на многопроцессорном железе в кольце 0.
О...respect.
Та не, это был только вопрос.
Я подумал, если в ответ получу разработанную программу или хотя бы алгоритм использующий STL, то внеочереди выучу ту книгу. Но повезло :D.
Куда-то делся один пост rostyslav'а
я убрал. решив, что вопросы Green-унужно было бы задать на другом топике. Этот топик о regex.
я убрал. решив, что вопросы Green-унужно было бы задать на другом топике.
Я думаю что ваша беседа здесь не нарушение правил, главное что тема идёт (или шла) по своему руслу, а паралельно органично текла вторая тема, и что форум выполняет свою функцию - вопросы - ответы, обмен мнениями.
Думаю модератор не будет серчать :)
using namespace std;
using namespace boost;
из main.cpp в main.h
Прошу не принимать заявленное здесь близко к сердцу...
Просто я, скажем поклонник g++ (или чего-то другого, "неBuilder'а"), привык видеть конструкцию (участок кода) вот таким, и если что-то в нём не так, у меня возникает естественное чувство недоумения, которое я и высказываю, но это выражается вовсе не с целью задеть кого-либо.
Ты меня не задел. Давай не принимая ничего близко к сердцу разберем причину твоего естественного чуства недоумения.
Решилось :!!!: Как ты сказал, Green, всё решается указанием префикса boost::, либо если перенести (конечно же!) строки
using namespace std;
using namespace boost;
из main.cpp в main.h
Обалдеть!
Первым, это тебе сказал "глупый билдер":
>>(C++ Error) main.h(32): E2303 Type name expected
>>(C++ Error) main.h(32): E2139 Declaration missing ;
Подсветить ошибку и нажать F1. Английский Я не учил, но моего сл. запаса и одной прочитанной книги по С++(на русск.)хватает понять, что достаточно было указывать префикс, либо поднять все пространство имен на тек. уровень видимости(using).
И причем скажите тут Билдер? Разве в VC++ не нужно указывать область видимости? Билдер просто "орал" тебе об этом! Детский сад.
Вторым GIZMO:
...
>>В поле Type введи Boost::Regex
Думал вопрос по мастеру, а тут по С++ оказывается и не заострил на этом внимания.
Третьим Green:
>>При беглом просмотре заметил, что ты не указываешь область видимости для boost.
Совершенно не пытался тебя задеть просто искренне не понимаю причину твоего недоумения. Надо быть внимательнее. С++ в билдере такойже как и в Африке!
АГРОМНОЕ спасибо!
Только вот спрашивал я не у тебя...
Да ладно, обиделся что-ли? Ну пошутил маленько, извиняюсь.
Может, компилятор Борланда не может проглатить эту реализацию regex? Ты используешь какую-то портированную под этот компилятор версию?
Может. У 5-ки и 6-ки STL разные. В 6-ке STLPort.
У него (у компилятора Борланда) множество проблем с шаблонами.
?
Green ну не грузи пацанов, зарузи Билдер. Разберись с опциями компилятора (в Билдере не только мышкой кликать можно). Приведи примеры реальные. С чего ты взял, что проблемы с шаблонами или несоответствие ANSI?
Green ну не грузи пацанов, зарузи Билдер. Разберись с опциями компилятора (в Билдере не только мышкой кликать можно). Приведи примеры реальные. С чего ты взял, что проблемы с шаблонами или несоответствие ANSI?
Я приведу несколько примеров.
Скажи мне параметры при которых они скомпилируются, а так же результаты работы этих примеров.
#include <iostream>
template <class T>
size_t func(T& ptr)
{ return sizeof(T); }
int main()
{
std::cout << func("12345") << std::endl;
return 0;
}
// Этот баг Борданд вроде бы убрал, но проверка не помешает
#include <iostream>
template<class T>
struct A
{
enum {val=0};
};
template<int N>
struct A<char[N]>
{
enum {val=N};
};
int main()
{
std::cout << A<char[5]>::val << std::endl;
return 0;
}
#include <iostream>
template<class T, class U>
class B
{
public:
enum{val=0};
};
template<class T>
class B<class T, int>
{
public:
enum{val=1};
};
int main()
{
std::cout << B<int,int>::val << std::endl;
return 0;
}
#include <iostream>
#include <vector>
class A
{
};
template< template<class,class> class Container=std::vector>
class B: private Container< A, std::allocator<A> >
{
public:
using Container< A, std::allocator<A> >::size;
};
int main()
{
B<> b;
std::cout << b.size() << std::endl;
return 0;
}
#include <iostream>
template<class F,class Func>
void execute(F& f, Func func)
{
func(f.n);
}
template<class T>
class X
{
public:
T get() { return n; }
private:
T n;
template<class F,class Func>
friend void execute(F& f, Func func);
};
struct D
{
void operator()(int &b) { b = 7; }
};
int main()
{
X<int> x;
execute(x, D());
std::cout << x.get() << std::endl;
return 0;
}
Если что-то из этого будет работать, я буду только рад. Значит прогресс не стоит на месте.
Жду результатов. Порадуй нас.
Привет NightSleeper!
Обалдеть!
Первым, это тебе сказал "глупый билдер"
Вторым GIZMO
Третьим Green:
Привет и тебе!
С чайником свяжешься - часто вот так получается...
Думал вопрос по мастеру, а тут по С++ оказывается
Просто когда с мастером решилось, стало интересно как сделать ручками (а кому не интересно?). Каюсь что не написал результатов использования мастера.
Я приведу несколько примеров.
Скажи мне параметры при которых они скомпилируются, а так же результаты работы этих примеров.
Green, как всегда, ругает Билдер, из года в год приводя одни и те же примеры. Если ты такой непримиримый враг Борланд, что ты в этой конференции делаешь? Иди в конфу по мелкомягкому висуальному, в котором, кстати, наверняка тоже много глюков (недаром уже шестой сервиспак для VC98 вышел), только у нас были другие занятия нежели эти глюки выискивать.
Кстати, я хоть и не знаток стандарта C++, но всё-таки хочу спросить: почему ты считаешь, что первый пример (другие примеры просто не запускал) неверно работает именно в Борланде, а не в висуальном? Ведь Билдер всё верно печатает, размер ссылки -- 4 байта, передаётся же ссылка на массив, а не сам массив.
Привет и тебе!
С чайником свяжешься - часто вот так получается...
Да ладно. Сам Я тоже ... Единственно, что если что-то не собирается, не компилится и т. д. Я сразу грешу на себя. Так обычно и оказывается(виноватя мои руки растущие не из плеч..).
Просто когда с мастером решилось, стало интересно как сделать ручками (а кому не интересно?). Каюсь что не написал результатов использования мастера.
Ручками как обычно, толко не лезь в секцию _published об этом и Билдер говорит:
- // IDE-managed Components
по крайней мере пока не освоишься, а так и там можно поковыряться.
Еще "про мастра":
Чтобы получить обычное поле (член данных, member или как там еще...), в мастре просто выбери New Field(вместо New Property) и никаких аттрибутов.
Будь здоров NightSleeper!
Green, как всегда, ругает Билдер, из года в год приводя одни и те же примеры. Если ты такой непримиримый враг Борланд, что ты в этой конференции делаешь? Иди в конфу по мелкомягкому висуальному, в котором, кстати, наверняка тоже много глюков (недаром уже шестой сервиспак для VC98 вышел), только у нас были другие занятия нежели эти глюки выискивать.
Враг? Да кто такой Борланд Билдер, чтоб быть мне врагом?
Тебе не кажется, что ты относишься к инструменту (BCB), как к божественному созданию? Священные войны BCB и VC++... Смешно.
Я не ругаю биджер, а привожу конкретные замечания по его работе. Эти "особенности" надо знать. Их не надо выискивать специально, хотя и это не повредит. Надо знать тот инструмент, с которым работаешь или которому покланяешься.
GIZMO попросил показать "примеры реальные", что я и сделал.
А примеры одни и теже потому, что не исправляет никто эти баги "из года в год".
Что касаемо VC++ я и некоторые его баги знаю.
Кстати, я хоть и не знаток стандарта C++, но всё-таки хочу спросить: почему ты считаешь, что первый пример (другие примеры просто не запускал) неверно работает именно в Борланде, а не в висуальном? Ведь Билдер всё верно печатает, размер ссылки -- 4 байта, передаётся же ссылка на массив, а не сам массив.
Да нет... не верно он печатает...
Смотрим стандарт:
http://www.csci.csusb.edu/dick/c++std/cd2/expr.html#expr.sizeof
2 When applied to a reference or a reference type, the result is the size of the referenced type.
Давай попробуем на примере без шаблона.
typedef char ch6[6];
size_t func2(ch6& ptr)
{ return sizeof(ptr); }
int main()
{
std::cout << func2("12345") << std::endl;
return 0;
}
Что вернул Билдер?
Мне действительно интересно потому, что нет под рукой сейчас Билдера.
Я приведу несколько примеров.
Скажи мне параметры при которых они скомпилируются, а так же результаты работы этих примеров.
А чего сам-то? Поставь BCB и вперед. Похоже, что это нужно только тебе, а не тем кто на этом форуме. Не забудь зайти на вкладку Options|Advanced Compiller или через #pragma options!
Порадуй нас.
Радуйся...
http://www.comizdat.com/3/4/6/3810/
А чего сам-то?
Трудно найти что-то чего нет. Я о параметрах при которых указанные выше тесты скомпилировались бы.
Похоже, что это нужно только тебе, а не тем кто на этом форуме.
А вот это плохо. Надо объективнее смотреть на вещи, а не орать что круче BCB или VC++.
Давайте вернемся к началу ветки. Человек задал вопрос связанный с использованием библиотеки (не лишенной шаблонов, кстати) в BCB. Я предположил, что если библиотека не портирована специально под конкретную версию компилятора, то проблемы могли возникнуть из-за шаблонов. И началось... Наступили на больную мозоль? Раслабтесь, я спорить о том, что круче не собираюсь. Хотели, чтоб я привел примеры недостатков, пожалуйста. Опять не угодил... Трудно дается объективность?
Мне не интересны "научно-популярные" статьи, в принципе, как и затронутая именно в этой тема.
Враг? Да кто такой Борланд Билдер, чтоб быть мне врагом?
Ага... У меня нет мании величия, по-настоящему великие люди этой болезни не подвержены. ;-)
Нет, я к нему так не отношусь и "священные войны" тоже считаю глупым занятием. Просто достало уже, что программеры VC++ постоянно свысока (часто совершенно безосновательно) смотрят на програмеров BCB, мол, "борландовцы" неполноценная раса. Как, впрочем, и пользователи Маков с высока смотрят на пользователей PC. Наболело просто.
Смотрим стандарт:
http://www.csci.csusb.edu/dick/c++std/cd2/expr.html#expr.sizeof
Давай попробуем на примере без шаблона.
typedef char ch6[6];
size_t func2(ch6& ptr)
{ return sizeof(ptr); }
int main()
{
std::cout << func2("12345") << std::endl;
return 0;
}
Что вернул Билдер?
Мне действительно интересно потому, что нет под рукой сейчас Билдера.
6. Он печатает "6".
А пример с темплейтом печатает он верно. Ворнинг видел внизу: "Temporary used for ..."?
Этот ворнинг говорит о том, что билдер не может передать как аргумент ссылку на константу, и правильно, раз мы ссылку куда-то передаём, значит, переменная измениться может, а как мы адрес константы изменим? Создаётся временная переменная типа char* (именно указатель, ведь объект он в общем случае не имеет права копировать и вычислить sizeof(выражения) в общем случае он тоже не может). А какой у char* размер, угадайте с трёх раз?
Так что, имхо, всё в соответствии со стандартом.
Хотел вот ещё спросить: в стандарте C++ описана такая полезная фенечка VC++ как директива #import?
Ага... У меня нет мании величия, по-настоящему великие люди этой болезни не подвержены. ;-)
Билдер - это инструмент. Если я не буду злиться и считать врагом молоток, упавший мне на ногоу, то диагнозом будет мания величия?
Нет, я к нему так не отношусь и "священные войны" тоже считаю глупым занятием. Просто достало уже, что программеры VC++ постоянно свысока (часто совершенно безосновательно) смотрят на програмеров BCB, мол, "борландовцы" неполноценная раса. Как, впрочем, и пользователи Маков с высока смотрят на пользователей PC. Наболело просто.
Я не считаю себя "программером VC++", т.к. использую множество различных инструментов и компиляторов.
Если ты найдешь в этой ветке хоть один упрек неполноценности пользователей BCB, Я ГОТОВ ПРИНЕСТИ СВОИ ПУБЛИЧНЫЕ ИЗВЕНЕНИЯ.
Пока я говорил о некоторой трепетности и даже поклонению к бездушному и далеко неидеальному инструменту.
А пример с темплейтом печатает он верно.
Какая разница между примером с шаблонами и примером без них?
В примере с шаблоном шаблон инстанируется типом const char[6] и уже ничем не отличается от примера без шаблона.
Ворнинг видел внизу: "Temporary used for ..."?
Этот ворнинг говорит о том, что билдер не может передать как аргумент ссылку на константу, и правильно, раз мы ссылку куда-то передаём, значит, переменная измениться может, а как мы адрес константы изменим?
ЕРУНДА!
Ну измени пример с шаблоном без константы и проверь:
template <class T>
size_t func(T& ptr)
{ return sizeof(T); }
int main()
{
char str[] = "12345";
std::cout << func(str) << std::endl;
return 0;
}
Создаётся временная переменная типа char* (именно указатель, ведь объект он в общем случае не имеет права копировать и вычислить sizeof(выражения) в общем случае он тоже не может).
И куда же указывает этот указатель? :)
Ты запутываешь сам себя... Указатель он создает, а ссылку создать не может...
Так что, имхо, всё в соответствии со стандартом.
Конкретный пунк стандарта, плз, иначе это пустые слова.
Неужели так трудно признать, что это баг?
Наверное это противоречит концепции идеальности Билдера и угнетает всю "рассу Билдеровцев"?
Хотел вот ещё спросить: в стандарте C++ описана такая полезная фенечка VC++ как директива #import?
Нет, не описана.
А какое это отношение имеет к компилятору и обсуждаемой теме?
Это расширение предпроцессора (даже не компилятора) VC++. Многие компиляторы вводят свои расширения предпроцессора.
Этим ты хотел сказать, что баг c шаблонами на самом деле расширение компилятора Билдера? :D:D
Какая разница между примером с шаблонами и примером без них?
В примере с шаблоном шаблон инстанируется типом const char[6] и уже ничем не отличается от примера без шаблона.
Ну измени пример с шаблоном без константы и проверь:
template <class T>
size_t func(T& ptr)
{ return sizeof(T); }
int main()
{
char str[] = "12345";
std::cout << func(str) << std::endl;
return 0;
}
6. Он печатает "6".
Ты запутываешь сам себя... Указатель он создает, а ссылку создать не может...
До выполнения функции -- на строку "12345". после выполнения функции (непосредственно перед своей "смертью") -- зависит от функции. А что, разве непонятно? А ссылка -- это неявный указатель, и она, как видишь, создаётся.
Ты его сам недавно сюда запостил.
Неужели так трудно признать, что это баг?
Наверное это противоречит концепции идеальности Билдера и угнетает всю "рассу Билдеровцев"?
Это не баг. Ворнинг выдаётся? Выдаётся. Как было указано выше, это особенность компилятора, и, имхо, данная особенность более правильная, чем соотв. особенность VC++ создавать ссылки на константы. Кстати, ты ехидничаешь. Значит, ты неправ. :D
Не хотел. Не надо домысливать.
Чуть не забыл:
Слова "кто такой" применим к одушевлённым объектам, что говорит о том, что это _ты_ одушевляешь среду разработки. И в то же время говоришь: "инструмент". Ты уж определись: Borland C++ Builder -- инструмент или же что-то одушевлённое?
6. Он печатает "6".
Честно?
Тогда это вообще непонятный баг!
В стандарте нет разграничения для данного случия для const и не-const.
До выполнения функции -- на строку "12345". после выполнения функции (непосредственно перед своей "смертью") -- зависит от функции. А что, разве непонятно? А ссылка -- это неявный указатель, и она, как видишь, создаётся.
Если передается указатель на строку, то ничто не защищает строку от изменения так же как и при передаче ссылки.
Какой смысл в передаче указателя? Чтоб изменить его значение? Для чего?
Приведи пример, где есть необходимость в этом указателе.
Ты его сам недавно сюда запостил.
Укажи, плз, конкретное место в стандарте для тех, кто в танке.
Это не баг. Ворнинг выдаётся? Выдаётся. Как было указано выше, это особенность компилятора, и, имхо, данная особенность более правильная, чем соотв. особенность VC++ создавать ссылки на константы.
Никто не запрещает создавать ссылки на константы, так же как и указатели. Если ты не согласен, приведи конкретное место в стандарте.
Что тогда по твоему обозначает запись:
const char&
А особенность эта не только в VC++, но и в gcc, comeau. Кстати, считается, что Comeau ближе всех остальных к стандарту. Можешь сам убедиться, что от выдает в он-лайн версии Comeau.
Только надо будет немного изменить пример, чтоб увидеть результат уже при компиляции:
int func(T& ptr)
{
int chk[sizeof(T)-6]; // эта строка для проверки
return sizeof(T);
}
int main()
{
func("12345");
return 0;
}
Если моя позиция верная ( sizeof(T)==6 ), то в строке проверки будет попытка создания массива нулевой длины и компилятор выдаст ошибку.
Смотрим, что выдает компиятор
"ComeauTest.c", line 4: error: the size of an array must be greater than zero
int chk[sizeof(T)-6];
^
detected during instantiation of
"int func(T &) [with T=const char [6]]"
Обрати внимание, каким типом инстанируется шаблон:
with T=const char [6]
Аналогично ведет себя и gcc.
Кстати, ты ехидничаешь. Значит, ты неправ. :D
Еслиб этим решалось, кто прав, кто нет.
Пока я не услышал от тебя что-либо вразумительного, одни расплывчатые предположения, никаких конкретных фактов и документов.
Слова "кто такой" применим к одушевлённым объектам, что говорит о том, что это _ты_ одушевляешь среду разработки. И в то же время говоришь: "инструмент". Ты уж определись: Borland C++ Builder -- инструмент или же что-то одушевлённое?
Ну давай будем еще спорить о русском языке... Может,к знакам препинания предеремся?
Тебе больше нравится такая фраза:
"Враг? Да что такое Борланд Билдер, чтоб быть мне врагом?"
Звучит коряво, т.к. "кто такой" применяется в контексте "враг". Исторически сложилось, что враг - это одушевленный предмет.
Об этом я спорить не собираюсь.
P.S. Как утомляют споры, когда человек базируется на собственных суждениях и домыслах, а не на конкретных фактах и стандартах. Я не поленился пролистать стандарт, проверить работу других компиляторов, вынести решение и представить результаты. Не поленись и ты, инача это больше напоминает спор с некомпетентными людьми.
P.S. Как утомляют споры, когда человек базируется на собственных суждениях и домыслах, а не на конкретных фактах и стандартах. Я не поленился пролистать стандарт, проверить работу других компиляторов, вынести решение и представить результаты. Не поленись и ты, инача это больше напоминает спор с некомпетентными людьми.
Ну так не спорь. Можешь считать меня некомпетентным, если тебе так хочется. Мне спорить надоело, я заканчиваю. Остаюсь при своём мнении.
Желаю тебе приятного программирования с использованием полностью соответствующих стандартам компиляторов и плодотворных споров с компетентными людьми.