我想使用OPENARRAY
(或替代方法,如果有的话)将多个占位符变量传递给我的函数。我知道它可以通过这种方式用于String::Format
:
UnicodeString Text1 = "abc";
int Num2 = 1;
String::Format("Some %s and %d", OPENARRAY(TVarRec, (Text1, Num2));
我想要的是使用Text1和Text2变量:
MyFunction("Some %Txt1 and %Num2", OPENARRAY(TVarRec, ("%Txt1", Text1, "%Num2", Num2));
或者也许:
MyFunction(OPENARRAY(TVarRec, ("Some %Txt1 and %Num2", "%Txt1", Text1, "%Num2", Num2));
因此它接受文本并用适当的变量内容替换占位符变量。
我不知道的是如何从MyFunction读取OPENARRAY参数内容。
所以函数看起来像:
UnicodeString MyFunction(UnicodeString Txt, ?WHAT-HERE?)
{
// read openarray here and replace vars
return StringReplace(Txt, ?WHAT-HERE?);
}
所以我不知道如何接受OPENARRAY变量。此外,如果您有一个替代解决方案以类似的方式传递占位符,变量(不使用C ++ 11),那也是受欢迎的。
答案 0 :(得分:1)
将Delphi样式的Open Array传递给函数时,实际上传递了两件事:
指向数组第一个元素的指针
数组的最后一个元素的索引(不是数组的长度,正如您所料!)。
因此,在您的示例中,您可以声明您的函数:
UnicodeString MyFunction(UnicodeString Txt, const TVarRec *Values, const int Values_High)
然后使用普通指针算法循环遍历数组。
TVarRec
可以包含许多不同的数据类型,因此您必须查看其VType
字段以了解它实际引用的数据类型,然后访问相应的数据字段。有些值(整数和单个字符)直接存储在TVarRec
本身中,而其他值(字符串和其他类类型)则由指针引用。
例如:
UnicodeString MyFunction(UnicodeString Txt, const TVarRec *Values, const int Values_High)
{
if (((Values_High + 1) % 2) != 0)
throw Exception("uneven number of values!");
for (int index = 0; index <= Values_High; index += 2)
{
String OldValue, NewValue;
switch (Values[index].VType)
{
case vtString:
OldValue = * static_cast<const ShortString*>(Values[index].VString);
break;
case vtPChar:
OldValue = Values[index].VPChar;
break;
case vtPWideChar:
OldValue = Values[index].VPWideChar;
break;
case vtAnsiString:
OldValue = * static_cast<const AnsiString*>(Values[index].VAnsiString);
break;
case vtWideString:
OldValue = * static_cast<const WideString*>(Values[index].VWideString);
break;
case vtUnicodeString:
OldValue = * static_cast<const UnicodeString*>(Values[index].VUnicodeString);
break;
default:
throw Exception("illegal value type at index %d!", ARRAYOFCONST(( index )) );
}
switch (Values[index+1].VType)
{
case vtInteger:
NewValue = Values[index+1].VInteger;
break;
case vtBoolean:
NewValue = Values[index+1].VBoolean;
break;
case vtChar:
NewValue = Values[index+1].VChar;
break;
case vtExtended:
NewValue = * static_cast<const Extended*>(Values[index+1].VExtended);
break;
case vtString:
NewValue = * static_cast<const ShortString*>(Values[index+1].VString);
break;
case vtPChar:
NewValue = Values[index+1].VPChar;
break;
case vtWideChar:
NewValue = Values[index+1].VWideChar;
break;
case vtPWideChar:
NewValue = Values[index+1].VPWideChar;
break;
case vtAnsiString:
NewValue = * static_cast<const AnsiString*>(Values[index+1].VAnsiString);
break;
case vtCurrency:
NewValue = * static_cast<const Currency*>(Values[index+1].VCurrency);
break;
case vtVariant:
NewValue = * static_cast<const Variant*>(Values[index+1].VVariant);
break;
case vtWideString:
NewValue = * static_cast<const WideString*>(Values[index+1].VWideString);
break;
case vtInt64:
NewValue = * static_cast<const __int64*>(Values[index+1].VInt64);
break;
case vtUnicodeString:
NewValue = * static_cast<const UnicodeString*>(Values[index+1].VUnicodeString);
break;
default:
throw Exception("illegal value type at index %d!", ARRAYOFCONST(( index )) );
}
Txt = StringReplace(Txt, OldValue, NewValue, TReplaceFlags() << rfReplaceAll);
}
return Txt;
}
MyFunction("Some %Txt1 and %Num2", OPENARRAY(TVarRec, ("%Txt1", Text1, "%Num2", Num2)) );
在旁注中,当函数采用开放的TVarRec
值数组时,您应该直接使用ARRAYOFCONST()
宏而不是OPENARRAY()
宏,例如:
String::Format("Some %s and %d", ARRAYOFCONST(( Text1, Num2 )) );
MyFunction("Some %Txt1 and %Num2", ARRAYOFCONST(( "%Txt1", Text1, "%Num2", Num2 )) );