【问题标题】:C++ variadic template arguments: object is not forwarded as a referenceC++ 可变参数模板参数:对象不作为引用转发
【发布时间】:2021-04-09 11:49:08
【问题描述】:

假设我有以下代码:

#include <iostream>

struct NotCopyable
{
    std::string value;

    NotCopyable(const std::string& str) :
        value(str)
    {
    }
    
    // This struct is not allowed to be copied.
    NotCopyable(const NotCopyable&) = delete;
    NotCopyable& operator =(const NotCopyable&) = delete;
};

struct Printable
{
    NotCopyable& nc;

    // This struct is constructed with a reference to a NotCopyable.
    Printable(NotCopyable& inNc) :
        nc(inNc)
    {
    }

    // So that std::cout can print us:
    operator const char*() const
    {
        return nc.value.c_str();
    }
};

// This function constructs an object of type T,
// given some arguments, and prints the object.
template<typename T, typename... ARGS>
void ConstructAndPrint(ARGS... args)
{
    T object(std::forward<ARGS>(args)...);
    std::cout << "Object says: " << object << std::endl;
}

int main(int, char**)
{
    // Create a NotCopyable.
    NotCopyable nc("123");

    // Try and construct a Printable to print it.
    ConstructAndPrint<Printable>(nc);    // "Call to deleted constructor of NotCopyable"
    
    // OK then, let's make absolutely sure that we're forwarding a reference.
    NotCopyable& ncRef = nc;

    // Try again.
    ConstructAndPrint<Printable>(ncRef); // "Call to deleted constructor of NotCopyable"
}

似乎NotCopyable 没有被正确地作为引用转发,即使我明确提供了一个引用变量作为参数。为什么是这样?有什么方法可以确保转发引用,而不是复制构造的对象?

【问题讨论】:

  • 您必须使用转发引用 (&amp;&amp;)。我的意思是void ConstructAndPrint(ARGS &amp;&amp; ... args)
  • 它有点重复,但我无法找到那篇文章(确实没有找到),因为它是根据语言技术而不是本质转发的参数。我真正需要的信息是“转发参考”是一个事实,而不是我知道的std::forward

标签: c++ variadic-templates perfect-forwarding


【解决方案1】:
template<typename T, typename... ARGS>
void ConstructAndPrint(ARGS... args);

按值取参数,复制也是如此。

您想要转发参考:

// This function constructs an object of type T,
// given some arguments, and prints the object.
template<typename T, typename... ARGS>
void ConstructAndPrint(ARGS&&... args)
{
    T object(std::forward<ARGS>(args)...);
    std::cout << "Object says: " << object << std::endl;
}

【讨论】:

  • 太棒了,我不知道您可以将&amp;&amp; 应用于可变参数。这应该很好用,谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 2021-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多