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

时间:2019-01-24 06:57:06

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

我希望这个主题反映出我想在这里提出的问题...我已尽力而为。

我们必须根据几个运行时条件设置某些变量。我们总是选择if..else语句,但是我发现它们太麻烦了,尤其是考虑到可能存在多个条件时。我尝试使用c ++ 11/17功能进行开发,并提出了以下建议。

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

O(n)

2 个答案:

答案 0 :(得分:3)

如果需要考虑该函数的可读性,则可以始终使用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。但是,编译时间可能会受到影响。

我不喜欢这种巨大的可变参数函数调用,但是当它们在整个代码库中节省了大量键入内容时,有时它们是值得的。不知道真正的用例就很难说。

答案 1 :(得分:0)

老实说,我更喜欢use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** Seed the application's database **/ public function run() { $this->call(NationalitySeeder::class); } } 语句或if-else运算符。 更容易调试或解释故障转储。 非C ++开发人员或初学者可以更轻松地阅读。 而且没有明显的缺点。