将数组各种类型传递给微控制器上的规则引擎的要求。铸造有问题
Requirement to pass array various types to a rules engine on a microcontroller. Having problems with casting
对不起,我是社区和 c++ 的新手,请保持温柔。
首先,因为这是在微控制器上 运行,内存和编译代码 space 非常有价值。
我需要从各种来源获取输入并将其输入中央处理功能。输入的汇总参数将被命名,具有不同的类型,并允许进行类型检查,因此可以将它们与编译时未知的标准进行比较。我从各处借用了一些代码,并提出了以下内容。
template <typename T_ty> struct TypeInfo { static const char * name; };
template <typename T_ty> const char * TypeInfo<T_ty>::name = "unknown";
#define MAKE_TYPE_INFO( type ) template <> const char* TypeInfo<type>::name= #type;
// Type-specific implementations.
MAKE_TYPE_INFO( int );
MAKE_TYPE_INFO( float );
MAKE_TYPE_INFO( String );
MAKE_TYPE_INFO( char * );
MAKE_TYPE_INFO( bool );
class ParaBase
{
public:
char* _type ;
char* _name;
void* _child;
const char* name() { return _name; }
ParaBase(){}
ParaBase(const char* name, const char* type, const void * child )
:
_name( (char*) name ),
_type( (char*) type ),
_child( (void*) child ) {}
template <class U>
bool is()
{
return ( TypeInfo<U>::name == _type );
}
};
template <class T>
class Para : public ParaBase
{
T _value;
public:
Para( const char* name, const T value )
:
ParaBase( name, TypeInfo<T>::name, this ),
_value( value )
{}
Para( ParaBase& paraBase )
:
ParaBase( paraBase._name, paraBase._type, this )
{}
operator T() { return _value; }
const T value() { return _value; }
template <class U>
U as()
{
return *( ( U *) _value );
}
};
为了测试它,我执行以下操作:-
ParaBase para[3];
para[0] = Para<char*>("Param-one", "Hi");
para[1] = Para<bool> ("Param-two", true);
para[2] = Para<float>("Param-three", 2.05);
我可以将 para 提供给中央函数。
bool ok = para[1].is<bool>(); // is true
bool notok = para[1].is<char*>(); // is false
所以类型检查有效,是的!
Para<char*> testDownCast = ( Para<char*>) para[0] ;
char* orig = testDownCast.as<char*>();
嗯,不太好。主要失败在这里。我的 testDownCast 指针 (如果我使用的术语正确) 只包含垃圾。我做错了什么?
如有任何帮助,我们将不胜感激。在此先感谢您对新手的帮助。
你的问题出在这里:
ParaBase para[3];
para[0] = Para<char*>("Param-one", "Hi");
您将 Para 对象分配给 ParaBase 对象。由于 ParaBase 对象是 base 对象,它不会包含任何特定于 derived 对象 (Para) 的信息。在这种情况下,
T _value;
Para 对象丢失。然后将 ParaBase 对象分配回 Para 对象:
Para<char*> testDownCast = ( Para<char*>) para[0] ;
是正确的,但是para[0]对象不包含任何关于_value的信息,所以不能复制回testDownCast。
为了使您的示例工作,您应该更改 ParaBase 数组
ParaBase para[3];
到 ParaBase 指针数组
ParaBase* para[3];
Para<char*> realPara0("Param-one", "Hi");
para[0] = (ParaBase*)&realPara0; //Or use C++-style cast here
当然在这种情况下你不会有 ParaBase 对象,只有指向它们的指针。但是你可以转换回 Para 对象。当然,您必须调整其余代码。
顺便说一句 - 这不是好的低占用微控制器代码。对于您使用的每种模板类型,都会生成新代码。每次复制对象也会导致堆栈增长(这不是问题 直到 你有小对象)。 'Classic' 微控制器实现将依赖于 union,可能还有关于通过 union 传递的类型的附加信息。
我并不是要告诉不要在微控制器中使用 C++(我非常喜欢这个!),但是应该在意识到这一点的情况下完成。这是在嵌入式系统中使用 C++ 的精彩文章(两部分):
http://www.embedded.com/design/programming-languages-and-tools/4438660/1/Modern-C--in-embedded-systems---Part-1--Myth-and-Reality
对不起,我是社区和 c++ 的新手,请保持温柔。
首先,因为这是在微控制器上 运行,内存和编译代码 space 非常有价值。
我需要从各种来源获取输入并将其输入中央处理功能。输入的汇总参数将被命名,具有不同的类型,并允许进行类型检查,因此可以将它们与编译时未知的标准进行比较。我从各处借用了一些代码,并提出了以下内容。
template <typename T_ty> struct TypeInfo { static const char * name; };
template <typename T_ty> const char * TypeInfo<T_ty>::name = "unknown";
#define MAKE_TYPE_INFO( type ) template <> const char* TypeInfo<type>::name= #type;
// Type-specific implementations.
MAKE_TYPE_INFO( int );
MAKE_TYPE_INFO( float );
MAKE_TYPE_INFO( String );
MAKE_TYPE_INFO( char * );
MAKE_TYPE_INFO( bool );
class ParaBase
{
public:
char* _type ;
char* _name;
void* _child;
const char* name() { return _name; }
ParaBase(){}
ParaBase(const char* name, const char* type, const void * child )
:
_name( (char*) name ),
_type( (char*) type ),
_child( (void*) child ) {}
template <class U>
bool is()
{
return ( TypeInfo<U>::name == _type );
}
};
template <class T>
class Para : public ParaBase
{
T _value;
public:
Para( const char* name, const T value )
:
ParaBase( name, TypeInfo<T>::name, this ),
_value( value )
{}
Para( ParaBase& paraBase )
:
ParaBase( paraBase._name, paraBase._type, this )
{}
operator T() { return _value; }
const T value() { return _value; }
template <class U>
U as()
{
return *( ( U *) _value );
}
};
为了测试它,我执行以下操作:-
ParaBase para[3];
para[0] = Para<char*>("Param-one", "Hi");
para[1] = Para<bool> ("Param-two", true);
para[2] = Para<float>("Param-three", 2.05);
我可以将 para 提供给中央函数。
bool ok = para[1].is<bool>(); // is true
bool notok = para[1].is<char*>(); // is false
所以类型检查有效,是的!
Para<char*> testDownCast = ( Para<char*>) para[0] ;
char* orig = testDownCast.as<char*>();
嗯,不太好。主要失败在这里。我的 testDownCast 指针 (如果我使用的术语正确) 只包含垃圾。我做错了什么?
如有任何帮助,我们将不胜感激。在此先感谢您对新手的帮助。
你的问题出在这里:
ParaBase para[3];
para[0] = Para<char*>("Param-one", "Hi");
您将 Para 对象分配给 ParaBase 对象。由于 ParaBase 对象是 base 对象,它不会包含任何特定于 derived 对象 (Para) 的信息。在这种情况下,
T _value;
Para 对象丢失。然后将 ParaBase 对象分配回 Para 对象:
Para<char*> testDownCast = ( Para<char*>) para[0] ;
是正确的,但是para[0]对象不包含任何关于_value的信息,所以不能复制回testDownCast。
为了使您的示例工作,您应该更改 ParaBase 数组
ParaBase para[3];
到 ParaBase 指针数组
ParaBase* para[3];
Para<char*> realPara0("Param-one", "Hi");
para[0] = (ParaBase*)&realPara0; //Or use C++-style cast here
当然在这种情况下你不会有 ParaBase 对象,只有指向它们的指针。但是你可以转换回 Para 对象。当然,您必须调整其余代码。
顺便说一句 - 这不是好的低占用微控制器代码。对于您使用的每种模板类型,都会生成新代码。每次复制对象也会导致堆栈增长(这不是问题 直到 你有小对象)。 'Classic' 微控制器实现将依赖于 union,可能还有关于通过 union 传递的类型的附加信息。
我并不是要告诉不要在微控制器中使用 C++(我非常喜欢这个!),但是应该在意识到这一点的情况下完成。这是在嵌入式系统中使用 C++ 的精彩文章(两部分): http://www.embedded.com/design/programming-languages-and-tools/4438660/1/Modern-C--in-embedded-systems---Part-1--Myth-and-Reality