请查看下面的代码
template<typename T>
T GetValueFromDataType(Value &value)
{
T jsonValue;
if (value.IsString())
{
assert(value.IsString());
jsonValue = value.GetString(); // Here the error is showing
return jsonValue;
}
else if (value.IsInt())
{
assert(value.IsInt());
jsonValue = value.GetInt();
return jsonValue;
}
else if (value.IsDouble())
{
assert(value.IsDouble());
jsonValue = value.GetDouble();
return jsonValue;
}
else if (value.IsBool())
{
assert(value.IsBool());
jsonValue = value.GetBool();
return jsonValue;
}
}
jsonValue
在另一个函数中返回。在这里,我将返回变量声明为int。理想情况下,它应该接受int的情况。但是它给出了一个编译错误:
错误C2440 '=':无法从'const char *'转换为'int'
是否有办法使用上述代码或其他结构?
如果调用GetValueFromDataType<int>(...)
,则jsonValue
内部的类型为int
,而jsonValue = value.GetString();
将没有任何意义。不管value.IsString()
是假的,你有一个将会失败的assert
。如果有代码,那么它必须是有效的——除非您通过使用if constexpr
明确地将其排除在外。没有实例化if constexpr
的未取分支,因此其中的代码只进行轻量级检查(就像在未实例化的模板中一样)。不需要输入正确
坏:
assert(value.IsString());
jsonValue = value.GetString(); // this line will be fully checked
// regardless of the condition above
好:
if constexpr (std::is_same_v<T, std::string>) {
assert(value.IsString()); // make sure the value matches
jsonValue = value.GetString(); // this line will NOT be fully checked
// if the condition in the if statement
// (known at compile time) is false.
}
话虽如此,我不喜欢这种风格,如果可能的话,我更喜欢显式专门化。
template<typename T>
T GetValueFromDataType(Value &value);
template <>
std::string GetValueFromDataType<std::string>(Value &value) {
assert(value.IsString());
return value.GetString();
}
// etc.
原因是它更模块化。如果添加了新类型,则不必修改现有的函数。