提问人:intrigued_66 提问时间:11/9/2023 更新时间:11/9/2023 访问量:70
基于模板参数类型具有两种不同类型的条件运算符
Conditional operator with two different types based on type of template parameter
问:
我有一个执行数值计算的函数。在一个地方,它处理双精度,在第二个地方,它处理自定义算术类型。因此,该函数是以算术类型为模板的:
template<class T>
T calc(const T input_1)
{
}
如果函数是模板化的,我需要转换为 ,否则如果模板类型是 应该保留。double
input_2
double
MyNumber
input_2
我用条件运算符尝试过:
template<class T>
T calc(const T input_1)
{
const MyNumber input_2 = getFromElsewhere();
const T value = std::is_same_v<double, T> ? input_2.toDouble() : input_2;
return value + input_1; // example
}
但是,上面的内容无法编译,因为两个CMOV“分支”是不同的类型( vs )。double
MyNumber
我用静态的if-else替换了条件:
template<class T>
T calc(const T input_1)
{
const MyNumber input_2 = getFromElsewhere();
T value;
if constexpr(std::is_same_v<double, T>)
{
value = input_2.toDouble();
}
else
{
value = input_2;
}
return value + input_1; // example
}
但我不喜欢从中删除.const
const T value
有没有一种解决方案,我可以根据 的类型和 keep 切换输入源?T
const T value
答:
您可以调用专用于 double 的模板化函数。
template<class T>
T inline unsafeConvert(const MyNumber& input_2)
{
return input_2;
}
template<>
double inline unsafeConvert(const MyNumber& input_2)
{
return input_2.toDouble();
}
template<class T>
T calc(const T input_1)
{
const MyNumber input_2 = getFromElsewhere();
const T value = unsafeConvert<T>(input_2);
return value + input_1; // example
}
或者,您可以让模板化的转换函数包含 而不是定义专用化if constexpr
template<class T>
T inline unsafeConvert(const MyNumber& input_2)
{
if constexpr(std::is_same_v<double, T>)
{
return input_2.toDouble();
}
else
{
return input_2;
}
}
463035818_is_not_an_ai在注释中指出的另一个选项是立即调用的 Lambda。
template<class T>
T calc(const T input_1)
{
const MyNumber input_2 = getFromElsewhere();
const T value = [&](){
if constexpr(std::is_same_v<double, T>)
{
return input_2.toDouble();
}
else
{
return input_2;
}
}();
return value + input_1; // example
}
如果您唯一的特殊情况是 double,并且您正在使用此函数一次,则应立即使用此函数,但如果您经常重用此函数,那么您可能应该使用模板函数路由。
您可以通过将 convertible 转换为 来简化它,这意味着如果您愿意,可以删除成员函数:MyNumber
double
toDouble()
class MyNumber {
public:
//...
explicit operator double() const { return m_value; }
//...
};
然后,will 的实现不需要任何特殊性,除了 ,如果 是,它将不执行任何操作,否则使用转换运算符。calc
static_cast
T
MyNumber
template <class T>
T calc(const T input_1) {
const T value = static_cast<T>(getFromElsewhere());
return value + input_1; // example
}
如果既不是也不是,则不会编译,就像调用缺少该成员函数的类型(或非类型)一样。T
double
MyNumber
toDouble()
但是,您可以为 etc 添加更多重载,而无需更改 。然后会选择正确的一个,所以不需要等。explicit operator type () const
float
MyNumber
calc
static_cast<T>
toFloat()
评论
MyNumber
double
MyNumber
if else
MyNumber
double
const T value = [&]() { ... }();
并将 if 语句替换为 if 语句...