c++ - 针对简单 if..else 语句的递归 Variadic 函数调用的性能

标签 c++ c++11 c++17 variadic-templates variadic-functions

我希望这个主题反射(reflect)了我想在这里问的问题......我尽力了。

我们必须根据几个运行时条件设置某些变量。我们总是使用 if..else 语句,但我发现它们太麻烦了,尤其是考虑到可能有多个条件。我尝试使用 c++11/17 功能开发一些东西,并得出以下结论。

所以我的问题是关于:性能和可读性,您更愿意使用以下内容吗?

template <typename DST, typename... Ts>
void SetValue(DST& dst, Ts&&... ts)
{
  CheckAndSetVal(dst, std::forward<Ts>(ts)...);
}

template <typename DST>
void CheckAndSetVal(DST&) {}

template <typename DST, typename T1, typename T2, typename... Ts>
std::enable_if_t<std::is_same_v<DST, T2> > CheckAndSetVal(DST& dst, T1&& cond, T2&& val, Ts&&... ts)
{
  if (cond())
    dst = val; // Assign the value here ...
  else
    CheckAndSetVal(dst, std::forward<Ts>(ts)...);
}

template <typename DST, typename T1, typename T2, typename... Ts>
std::enable_if_t<!std::is_same_v<DST, T2> > CheckAndSetVal(DST& dst, T1&& cond, T2&& val, Ts&&... ts)
{
  if (cond())
    dst = val(); // Assign the value using this functor .. 
  else
    CheckAndSetVal(dst, std::forward<Ts>(ts)...);
}

  int i;
  //
  // In practive though the conditions are not as trivial as they look here. 
  //
  SetValue(i, []() { return false; }, 444
            , []() { return false; }, 999
            , []() { return true; }, []() { return 222; });

最佳答案

如果该函数的可读性是一个问题,您总是可以使用 C++17 摆脱很多 SFINAE 魔法 :)

#include <functional>
#include <type_traits>

template<class DestT, class CondT, class ValueT, class... Ts>
void SetValue(DestT& out, CondT&& cond, ValueT&& value, Ts&&... ts)
{
    if (cond())
    {
        if constexpr (std::is_invocable_v<ValueT>)
        {
            out = value();
        }
        else
        {
            out = value;
        }
    }
    else
    {
        if constexpr (sizeof...(Ts) != 0)
        {
            SetValue(out, std::forward<Ts>(ts)...);
        }
    }
}

int main()
{
    int i;
    SetValue(i, []() { return false; }, 444,
                []() { return false; }, 999,
                []() { return true; }, []() { return 222; });

    return i;
}

发布版本的性能应该完全相同,未优化的版本可能会慢一点。例如,上面的代码在 gcc/clang 上经过优化编译为 return 222。不过,编译时间可能会受到一些影响。

我不喜欢像这样巨大的可变函数调用,但有时它们是值得的,因为它们可以在整个代码库中节省大量输入。在不了解您的真实用例的情况下很难判断。

关于c++ - 针对简单 if..else 语句的递归 Variadic 函数调用的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54340936/

相关文章:

c++ - static_cast int 引用 int?

c++ - 在数组上使用迭代器

c++ - C++17 中的歧义错误(模板模板参数和默认参数问题)

c++ - 返回字符串及其 .c_str() 的生命周期

c++ - 在 C++ 中解析二进制消息。有例子的库吗?

c++ - 为什么 C++11 不支持 'std::function<void(int, ...)>' ?

c++ - 模板参数部分关于包扩展的一些困惑

c++ - C++17 的 std::inserter 替代品

c++ - 为什么VC++引入非标准关键字: __leave?

c++ - 基于模板参数值的类型