12

我有这个示例程序:

#include <iostream>

template<typename Message, typename Decoration, typename PrintImpl>
void print_surrounded(Message&& msg, const Decoration& decoration, const PrintImpl& print_impl)
{
    print_impl(decoration); // should forward be used?
    print_impl(" ");
    print_impl(std::forward<Message>(msg));
    print_impl(" ");
    print_impl(decoration);
}

template<typename Message, typename PrintImpl>
void pretty_print(Message&& msg, const PrintImpl& print_impl)
{
    print_surrounded(std::forward<Message>(msg), "***", print_impl);
}

int main()
{
    pretty_print("So pretty!", [](const char* msg) {
        std::cout << msg;
    });
}

我也把它贴在 Coliru 上。

如您所见,我使用不同的方式来传递参数:

  • 消息作为通用引用传递,因为它最终需要转发到 PrintImpl 函数。
  • 装饰在这里作为 const ref 传递,因为它的值被使用了两次,我不确定使用两次转发是否安全。(它可能会被第一个前锋移开?)
  • PrintImpl 作为 const 引用传递,因为我看不到任何使用 forward 的理由。但是,我不确定这是否明智。(我应该过去&&吗?如果是,我也应该使用std::forward吗?)

我是否做出了正确的选择?

4

1 回答 1

4

我是否做出了正确的选择?

是的(大部分)。

装饰在这里被捕获为 const ref,因为它的值被使用了两次,我不确定使用 forward 两次是否安全。(它可能被第一个前锋移开?

std::forward当您多次执行此操作时,请勿使用,这正是您布置的原因。

PrintImpl 被捕获为 const 引用,因为我看不到任何使用 forward 的理由。

您可能想要做的是PrintImpl&&使用而不使用(将它们保留为左值),允许传递没有-qualified的std::forward函数对象。constoperator()

于 2013-07-25T09:34:42.380 回答