仅在未被 std::enable_if 禁用时才调用成员函数
call member function only if not disabled by std::enable_if
我正在编写一个函数来计算数值流的各种统计数据。它有各种模板参数来有条件地计算其他更昂贵的东西,如中位数和众数。它们是模板,因此编译器将优化所有 if
语句。根据模板值,如果未计算更昂贵的值的吸气剂将被禁用。
template <bool CalcMedian>
class Stats
{
public:
// median getter, disabled if it wasn't calculated
template <bool B = CalcMedian, typename = std::enable_if_t<B>>
double median() const { return _median; }
void add_element(double value) {
// update easy values
if (CalcMedian) {
// update the median
}
}
};
一切都很好,除了我为了 class.
超载 <<
template <bool CalcMedian>
std::ostream& operator<<(std::ostream& o, const Stats<CalcMedian>& stats) {
// display the easy stats
if (CalcMedian) {
o << "median = " << stats.median();
// g++: no matching function call for Stats<false>::median()
}
}
一个解决方案是专门化 class 以删除吸气剂,或者 operator<<
使其不使用 if
语句,但我计划至少包含 3 个参数,这已经是我必须编写的函数的 8 个变体。添加任何更多的模板参数将是一个巨大的痛苦。
我已经尝试过this answer中说明的方法,但是没有用。测试方法给出 true_type
因为该方法确实存在,它只是被 enable_if
禁用所以我得到相同的编译器错误。有没有办法修改该答案以捕获该功能存在但被禁用的事实?
您可以创建一个 display_median
专门的:
template <bool B = CalcMedian>
std::ostream&o display_median(std::ostream&o) const;
template <>
std::ostream&o display_median<true>(std::ostream&o) const;
{
return o << "median = " << median() << std::endl;
}
template <>
std::ostream&o display_median<false>(std::ostream&o) const;
{
return o;
}
然后
template <bool CalcMedian>
std::ostream& operator<<(std::ostream& o, const Stats<CalcMedian>& stats) {
// display the easy stats
stats.display_median<CalcMedian>(o);
}
我正在编写一个函数来计算数值流的各种统计数据。它有各种模板参数来有条件地计算其他更昂贵的东西,如中位数和众数。它们是模板,因此编译器将优化所有 if
语句。根据模板值,如果未计算更昂贵的值的吸气剂将被禁用。
template <bool CalcMedian>
class Stats
{
public:
// median getter, disabled if it wasn't calculated
template <bool B = CalcMedian, typename = std::enable_if_t<B>>
double median() const { return _median; }
void add_element(double value) {
// update easy values
if (CalcMedian) {
// update the median
}
}
};
一切都很好,除了我为了 class.
超载<<
template <bool CalcMedian>
std::ostream& operator<<(std::ostream& o, const Stats<CalcMedian>& stats) {
// display the easy stats
if (CalcMedian) {
o << "median = " << stats.median();
// g++: no matching function call for Stats<false>::median()
}
}
一个解决方案是专门化 class 以删除吸气剂,或者 operator<<
使其不使用 if
语句,但我计划至少包含 3 个参数,这已经是我必须编写的函数的 8 个变体。添加任何更多的模板参数将是一个巨大的痛苦。
我已经尝试过this answer中说明的方法,但是没有用。测试方法给出 true_type
因为该方法确实存在,它只是被 enable_if
禁用所以我得到相同的编译器错误。有没有办法修改该答案以捕获该功能存在但被禁用的事实?
您可以创建一个 display_median
专门的:
template <bool B = CalcMedian>
std::ostream&o display_median(std::ostream&o) const;
template <>
std::ostream&o display_median<true>(std::ostream&o) const;
{
return o << "median = " << median() << std::endl;
}
template <>
std::ostream&o display_median<false>(std::ostream&o) const;
{
return o;
}
然后
template <bool CalcMedian>
std::ostream& operator<<(std::ostream& o, const Stats<CalcMedian>& stats) {
// display the easy stats
stats.display_median<CalcMedian>(o);
}