1

我正在阅读“C++17 - The Complete Guide”一书,我在第 107 页和第 108 页遇到了关于 C++17 中折叠表达式的示例:

template<typename First, typename... Args>
void print(First first, const Args&... args)
{
    std::cout << first;
    auto outWithSpace = [](const auto& arg)
    {
        std::cout << " " << arg;
    };
    (..., outWithSpace(args));
    std::cout << "\n";
}

作者有什么理由不能这样做(没有将第一个参数与其余参数分开,也没有额外的打印空间!):

template<typename... Types>
void print(Types const&... args)
{
    ([](const auto& x){ std::cout << x << " "; }(args), ...);
    std::cout << "\n";
}
4

4 回答 4

3

正如你已经知道的那样,作者不能按照你的建议做,因为那样会留下额外的空间......</p>

作者本可以做的,就像

template<typename First, typename... Args>
void print(First first, const Args&... args)
{
    ((std::cout << first), ..., (std::cout << ' ' << args)) << '\n';
}

更确切地说

template <typename Arg, typename... Args>
std::ostream& print(Arg&& arg, Args&&... args)
{
    return ((std::cout << std::forward<Arg>(arg)), ..., (std::cout << ' ' << std::forward<Args>(args))) << '\n';
}

活的例子在这里

于 2019-12-16T22:59:56.233 回答
0

因为我们和朋友们玩得很开心

template<typename First, typename... Args>`
void print(First&& first, Args&&... args)
{
    auto emit = [](auto&&...x) { ((std::cout << x), ...); };

    (emit(first), ..., emit(' ', args)), emit('\n');
}

:)

于 2019-12-17T18:19:53.830 回答
0

显然,写这个的可读方式是

template<typename... Types>
void print(Types const&... args)
{
    std::size_t n = 0;
    (std::cout << " " + !n++ << args), ...);
    std::cout << '\n';
}

(有std::forward味道)。做这种废话的诱惑(bool first如果 C++17 没有杀死那个美妙template for的特性,它可能会使用)是为 C++23 计划的特性的动机。

于 2019-12-17T03:24:57.020 回答
-1

不,这只是审美问题。没有更多的理由。

于 2019-12-16T22:46:44.757 回答