我有一个自定义变体类型,并希望使用printf格式字符串格式化其实例。我发现这个相关的article描述了printf的可变参数模板的使用。
因此,这个VariantType可以采用不同类型之一,
typedef enum VariantValueType
{
VariantValueTypeInt32 = 1,
VariantValueTypeFloat = 2,
VariantValueTypeString = 3,
// ...
} MyVariantValueType;
并有一个支持union
来保持其实际价值。
typedef union VariantValue
{
long Int32;
float Float32;
const char* String;
// ...
} MyVariantValue;
现在我想在调用VariantTypes
printf
的值
template <typename ... Args>
void my_printf(char const * const format, Args const & ... args) noexcept
{
printf(format, Format(args, std::is_same<Args, VariantType>()) ...);
}
同时仍在处理内置类型,因为它们通常仅使用标记调度提供给printf
:
template<typename T>
T Format(T value, std::false_type)
{
return value;
}
和尝试解压缩变种
template<typename T>
T Format(T value, std::true_type)
{
VariantType var = static_cast<VariantType>(value);
switch (var.Type())
{
case VariantValueTypeInt32:
return var.Value().Int32;
case VariantValueTypeFloat:
return var.Value().Float32;
// ...
}
}
这会调用VariantType
的复制构造函数 - 这会导致意外输出:
my_printf("%s, %+03d\n", VariantType("test"), VariantType(5));
例如打印“test,+ 00”而不是“test,+ 05”。 我还尝试将模板定义为
// Variant
template<typename T, typename U>
U Format(T value, std::true_type) {}
// Non-Variant
template<typename T, typename U>
U Format(T value, std::false_type) {}
它似乎只适用于实际的Variant,不能为简单类型推导U
。
有没有办法更可靠地解包变体/演绎类型?