Быстрый / простой ответ: нет;при работе с шаблоном компилятор не будет генерировать правильные дескрипторы для обеспечения работы потоковой передачи.Тем не менее, так как это произошло раньше, я заглянул под крышку, чтобы выяснить, чего не хватает.И я обнаружил, что это почти там.Итак, вот немного больше информации.
В начале работы компилятор никогда не будет рассматривать тип на основе шаблона как Delphi.Например, сделайте что-то вроде этого:
void testing()
{
__classid(Mixin<Stdctrls::TLabel>); // Error Here
}
... и вы увидите ошибку
" Ошибка E2242 test.cpp 53: __classid требует Delphiтип класса стиля (т. е. класс, помеченный __declspec (delphiclass) или производный от System :: TObject) в функции testing () "
В основном это говорит о том, что компилятор не считает этот тип / класс совместимым с Delphi-классами [то есть те, которые являются производными от TObject].Внутренне на символе есть только флаг, который говорит, является ли тип delphi-совместимым или нет.И я заметил, что мог бы обмануть компилятор, чтобы он помечал тип как стиль delphi, если бы заставлял его идти вверх по иерархии ... это то, что он должен делать, если я создаю экземпляр объекта.Итак, с этим хаком ошибка исчезает:
void testing()
{
typedef Mixin<Stdctrls::TLabel> __ttype;
std::auto_ptr<__ttype> c2(new __ttype(0));
__classid(Mixin<Stdctrls::TLabel>); // No more errors here
}
Но гораздо приятнее было на самом деле использовать __declspec (delphiclass) непосредственно в шаблоне, как в:
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
Так что теперьчто компилятор рассматривает тип как класс в стиле delphi без хаков, я немного заглянул и обнаружил проблему, с которой вы, вероятно, сталкиваетесь: классы Delphi имеют поле TTypeData.PropCount - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData - которое являетсясумма свойств класса, включая свойства его базовых классов.Из-за того, как различные части информации вычисляются, компилятор выдает «0» для этого поля, когда задействован шаблон: (
Это можно увидеть, распечатав PropCount, как в:
#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>
class TCppComp : public Classes::TComponent {
int i;
public:
__fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
__property int AAAA = {read=i, write=i};
};
template <class T>
class __declspec(delphiclass) Mixin : public T {
private:
int i;
typedef T inherited;
public:
__fastcall Mixin(TComponent *owner) : inherited(owner) {};
};
typedef Mixin<TCppComp> TMixinComp;
void showProps(TClass meta) {
PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
int Count = GetPropList(pInfo, tkAny, NULL);
TAPtr<PPropInfo> List(new PPropInfo[Count]);
std::printf("Class: %s - Total Props:%d\n",
AnsiString(pInfo->Name).c_str(), Count);
GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
for (int i = 0; i < Count; i++) {
AnsiString propName(List[i]->Name);
std::printf("\t%s\n", propName.c_str());
}
}
void test() {
showProps(__classid(TCppComp));
showProps(__classid(TMixinComp));
}
int main() {
test();
return 0;
}
При запуске указанных выше отпечатков:
Class: TCppComp - Total Props:3
AAAA
Name
Tag
Class: @%Mixin$8TCppComp% - Total Props:0
IOW, Mixin обнаруживается с опубликованными свойствами '0', в то время как его базовый тип имеет 3: (*
Я подозреваюсистема потоковой передачи полагается на этот счетчик, и поэтому унаследованные свойства не записываются в вашу настройку.
Я рассмотрел настройку сгенерированных дескрипторов во время выполнения, но, поскольку мы записываем их в _TEXT, он обязательно вызывает DEP.
Я посмотрю на логику, которая вычисляет PropCount, чтобы увидеть, есть ли какой-нибудь способ заставить его вычислить правильное число. Если время позволяет, пожалуйста, откройте QC для этого: теперь, когда я заглянул внизу,Я полагаю, что это не потребовало бы больших усилий, чтобы заставить это работать как ожидалось.
Приветствия,
Бруно
PS: в моем образце у меня даже была публикация Mixinsh свойство и компилятор сгенерировал правильный дескриптор для этого свойства;тем не менее, общее количество было по-прежнему нулевым.