【问题标题】:Passing arguments to thread function (templated)将参数传递给线程函数(模板)
【发布时间】:2012-12-26 03:35:18
【问题描述】:

这个问题可能与Why does passing object reference arguments to thread function fails to compile?有关。

我遇到了类似的问题,但是,在我的例子中,仿函数是一个模板。

class A {
public:
  // Non template version works as expected!!.
  // void operator()(std::ostream& out){
  //    out << "hi\n";
  // }

  // template version doesn't. 
    template <class Ostream>
    void operator()(Ostream& out){
        out << "hi\n";
    }

};

int main() {
   A a;
   thread t(a, ref(cout));
   t.join();
}

GCC 说:

error: no match for 'operator<<' in 'out << "hi\012"'

我该如何解决这个问题?

【问题讨论】:

  • 由于线程使用参数打印一些东西,它似乎隐含地假设参数是一个ostream。这里真的需要模板吗?
  • @jogojapan:我尝试将其作为函数模板的原因是我还需要使用一些来自 boost 的 ostream。 boost/iostreams 和 boost/文件系统。阅读您的评论后,我尝试使用非模板版本传递 boost::filesystem::ofstream ,并且它有效!!。但我不确定它是否也适用于所有其他 ostream。
  • 它适用于从std::ostream派生的任何东西。对于输出流,最好从std::ostream 派生,除非您已经知道要使用的流类型不是从std::ostream 派生的,否则我会假设采用std::ostream &amp; 参数就足够了。

标签: c++ multithreading c++11


【解决方案1】:

您传递的是std::reference_wrapper。所以class Ostream 的类型将是std::reference_wrapper,这解释了错误。

template <class OstreamRef>
void operator()(OstreamRef& outRef){
    outRef.get()<< "hi\n";
}

这应该可以解决它。

对于非模板情况,当需要转换为std::ostream&amp; 时,会隐式调用get()。但是,使用模板不需要转换为任何其他类型,因此std::reference_wrapper 是按原样传递的,因此需要显式调用get()。谢谢@jogojapan

【讨论】:

  • 谢谢它的工作。这是我第一次遇到 get() 成员函数。简而言之,如果我将引用传递给非模板函数,则不需要使用 get()。但是,如果我将引用传递给模板函数,我应该使用 get()。上面这句话一般成立吗?
  • @Sungmin 不。您需要get(),因为您处理的是std::reference_wrapper,而不是参考。如果您的函数不是模板,但假定为 std::ostream &amp;,则引用包装器将自动转换为引用(即 get() 将被隐式调用)。但是对于模板,编译器在实例化模板时认为没有理由转换为std::ostream &amp;,因此它将其保留为引用包装器。此解决方案的问题(即显式调用get())是它仅在您传入引用包装器时才有效(不适用于ostream &amp;)。
猜你喜欢
  • 2022-01-12
  • 2011-08-26
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多