【问题标题】:Why I cannot pass std::make_unique<S> as a function parameter?为什么我不能将 std::make_unique<S> 作为函数参数传递?
【发布时间】:2021-10-10 06:06:44
【问题描述】:

谁能告诉我为什么我可以只用一个模板参数调用std::make_unique&lt;S&gt;,即S,像这样:

auto p = std::make_unique<S>(12, 13);

但是,我不能将 std::make_unique&lt;S&gt; 传递给一个函数来为我执行此操作,如下所示:

template <typename FuncType, typename ...Args >
void call_method(FuncType f, Args... args)
{
   f(std::forward<Args>(args)...);
}

struct S
{
   S(int x, int y) {}
};

int main()
{
   call_method(std::make_unique<S>, 12, 13); // not working
   // call_method(std::make_unique<S, int , int>, 12, 13); // works fine
   return 0;
}

编译器显示的错误是:

Error C2512 'S::S': no appropriate default constructor available.

我正在 Windows 10 上使用 Visual Studio 2017。

【问题讨论】:

  • 一个解决方案是通过[](auto &amp;&amp;... args) { return std::make_unique&lt;S&gt;(decltype(args)(args)...); }。
  • 顺便说一句,Args... args 不启用转发。
  • @StoryTeller-UnslanderMonica 声明Args&amp;&amp; ...args 将启用转发可能是个好主意
  • @Const 这是一个显示示例的简单代码。在实际代码中,我必须重用一个现有的方法,比如call_method。

标签: c++ c++11 templates unique-ptr


【解决方案1】:

std::make_unique 的签名是

template<class T, class... Args>
unique_ptr<T> make_unique(Args&& ...args);

如果你直接调用make_unique,编译器会使用模板参数推导来推断你调用它的Args应该是什么。通过将std::make_unique&lt;S&gt; 传递给您的函数,您声明Args 是一个空参数包,因此std::make_unique 期望零参数并尝试默认构造一个S。这与直接调用std::make_unique&lt;S&gt;(); 相同。

【讨论】:

    猜你喜欢
    • 2021-07-18
    • 1970-01-01
    • 2011-10-27
    • 2017-08-31
    • 1970-01-01
    • 2022-01-23
    • 2016-08-16
    • 2018-09-03
    相关资源
    最近更新 更多