c语言中折叠的意义,关于c ++:折叠表达式和cout

我有以下有效的代码,但我对其工作方式感到困惑。

template

void print(Args&&... args) {

(std::cout << ... << std::forward(args)) << '

';

}

int main()

{

print(1,2.0,"3");

}

输出:

123

我的困惑:

我希望能印出321。

我要这个命令:

cout << forward(args) << ...

但我无法编译...

您做了print(1,2.0,"3");并且期望了321吗?

@Holt链接的答案不是重复的。 (对于OPs帖子不完整)。 它只是说明了为什么会出现编译器错误。

@霍尔特,我同意这个问题不是重复的。 至少它没有给出如何以相反顺序打印值的答案

@PiotrNycz看起来像是尾巴(...)先被缠绕,然后是头(args)

zh.cppreference.com/w/cpp/language/fold

@NoSenseEtAl,...的位置指定左或右的关联性,但不更改参数的顺序-它使您可以在(std :: cout << x)<< y和std :: cout <

@DmitryGordon啊,那就是答案,谢谢,我希望这没有被关闭。 :)

...的位置指定左侧或右侧的关联性,但不更改参数的顺序-您可以在(std::cout << x) << y和std::cout << (x << y)之间进行选择。后者可能无法编译。

如果要以相反的顺序打印值,则需要使用一些技巧。这是示例:

#include

#include

template

struct ReversePrinter

{

ReversePrinter(T val) : val(val) { }

template

ReversePrinter< T > operator<& other) const

{

std::cout << other.val;

return *this;

}

T val;

};

template

std::ostream& operator<& val)

{

return stream << val.val;

}

template

void print(Args... args)

{

std::cout << (ReversePrinter(args) << ...);

}

int main()

{

print(100, 200, 300.0); //prints 300200100

}

多数民众赞成复制。

折叠表达式会尊重您使用的运算符的优先级和关联性。但是对于某些运营商,您可以做更多富有创意的左右折页。要考虑的唯一变量是操作数的顺序。 C ++ 17引入了赋值运算符左右之间的先于关系,因此它们的操作更加直观。右侧以及所有相关的副作用必须首先发生。

因此,一个完全独立的解决方案可以如下所示:

template

void print(Args&& ...args) {

int dum = 0;

(... = (std::cout << args, dum));

}

现场直播。

它使用逗号进行打印,同时以强制我们想要的评估顺序的方式为其分配dum。

模板魔术师的标准入门解决方案是std::index_sequence。

为了使参数可索引,可以使用std::tuple。

template <:size_t... n class t>

void print_reverse_impl(std::index_sequence, std::ostream& os, T t) {

(os << ... << std::get<:tuple_size_v t> - N - 1>(t));

}

template

void print_reverse(std::ostream& os, T&&... t) {

print_reverse_impl(std::make_index_sequence(), os, std::forward_as_tuple(t...));

}

不过,如果您的工具箱中有static_for()(您确实应该如此),则这会更简单:

template

void print_reverse(std::ostream& os, T&&... t) {

static_for([&](auto n){

os << std::get(std::forward_as_tuple(t...));

});

}

使用C ++ 20,也可以将其编写为:

void print_reverse(std::ostream& os, auto&&... t) {

[&](std::index_sequence, auto all){

(os << ... std::get(all));

}(std::make_index_sequence(), std::forward_as_tuple(t...));

}

顺便说一句,我切断了对std::forward的所有调用,因为无论如何,这些rvalue-references只会被标准库还原为lvalue-references。

有了很少的诡计,(目前还不能做得更好),您可以执行以下操作:

不确定是否有直接方法

// Your original function

template

void print(Args&&... args) {

(std::cout << ... << std::forward(args)) << '

';

}

template

struct changeorder;

template<>

struct changeorder<>

{

template

static void invoke(OtherArgs const&... otherargs)

{

print(otherargs...);

}

};

template

struct changeorder

{

template

static void invoke(T const& t, Args const&... args,

OtherArgs const&... otherargs)

{

// 1st parameter send first

changeorder::invoke(args..., t, otherargs...);

}

};

template

void reverseprint(A const& a, Args const&... args)

{

changeorder::invoke(args..., a);

}

Demo Here

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值