寻找一种根据条件使用不同可变参数函子的方法

问题描述 投票:0回答:1

我有一个运行时布尔值

verbose
,如果
false
排除一些打印到标准输出。 要确定想法,请考虑有很多部分,例如:

void add(const int a, const int b, const bool verbose)
{
    //...
    if(verbose) std::print("{}+{}={}\n", a, b, a+b);
}

我的目标是拥有类似的东西:

template<typename F>
void add(const int a, const int b, F print_if_verbose)
{
    //...
    print_if_verbose("{}+{}={}\n", a, b, a+b);
}

这样做的动机是简化代码并使其不易出错(忘记测试每次打印

verbose
),同时也是为了避免各个子系统了解
verbose
参数。

我的第一次尝试是(godbolt):

template<typename F>
void add(const int a, const int b, F print_if_verbose)
{
    print_if_verbose("{}+{}={}\n", a, b, a+b);
}

int main(const int, const char* const argv[])
{
    const bool verbose = get_verbose_arg(); // runtime boolean

    // This doesn't compile, types are different
    //const auto vprint = verbose ? [](const std::string_view msg, const auto&... args){std::vprint_unicode(msg, std::make_format_args(args...));}
    //                            : [](const std::string_view, const auto&...){};
    //add(1, 2, vprint);

    // This works, but ugly
    const auto verb_print = [](const std::string_view msg, const auto&... args){ std::vprint_unicode(msg, std::make_format_args(args...)); };
    const auto no_print = [](const std::string_view, const auto&...){};
    if(verbose) add(2, 3, verb_print);
    else        add(2, 3, no_print);

    // This works, but tests 'verb' each call
    const auto maybe_print = [verb=verbose](const std::string_view msg, const auto&... args){ if(verb) std::vprint_unicode(msg, std::make_format_args(args...)); };
    add(3, 4, maybe_print);
}

有没有一种方法可以让我在不每次都测试

verbose
的情况下获得一次分配函子的方法?

c++ variadic-templates variadic-functions functor
1个回答
0
投票

不确定我是否理解这个问题,但也许您正在寻找这个(为了简洁起见,省略了所有格式详细信息):

#include <iostream>
#include <string>

template <typename F>
void foo(F f) {
    f("hello");
}


int main() {
    const bool verbose = false;
    auto logger = verbose ? +[](const std::string& s){std::cout << s;} : [](const std::string& s) {};

    foo(logger);
}

是否打印某些内容的决定仅检查一次。

并非所有 lambda 都可以转换为函数指针,在最坏的情况下,您需要求助于具有 2 个实现的手写函子。您将无法避免分支或间接级别。无论是作为虚拟函数调用还是作为条件检查

bool
,对于运行时值,必须在某处做出一些决定。

© www.soinside.com 2019 - 2024. All rights reserved.