【问题标题】:template argument as functor template模板参数作为函子模板
【发布时间】:2011-11-04 13:26:18
【问题描述】:

我正在尝试创建一个从适配器执行函子的线程类。代码显示了我的尝试。

#include <iostream>

struct null_t { };

typedef void (*thread_func_t)();
typedef void (*thread_func_2_t)(int);

template <typename F, typename P = null_t>
class adapter
{
public:
    adapter(F f, P p = null_t()) : _f(f), _p(p) {}

    void operator ()() 
    {
        _f(_p);
    }
private:
    F _f;
    P _p;
};

template <typename T>
class thread
{
public:
    explicit thread(T f) : _f(f) { }

    void run()
    {
        _f();
    }
private:
    T _f;
};

void show_hello()
{
    std::cout << "hello" << std::endl;
}

void show_num(int x)
{
    std::cout << "show_num: " << x << std::endl;
}

int main()
{
    thread<adapter<thread_func_t> > t_a(adapter<thread_func_t>(&show_hello));

    t_a.run();

    int i = 666;
    thread<adapter<thread_func_2_t, int> > t_b(adapter<thread_func_2_t, int>(&show_num, i));
    t_b.run();
}

编译器错误:

$ /usr/bin/g++-4.4 func.cpp -o func
func.cpp: In function ‘int main()’:
func.cpp:51: error: request for member ‘run’ in ‘t_a’, which is of non-class type ‘thread<adapter<void (*)(), null_t> >(adapter<void (*)(), null_t>&)’

1) adapter 不准备调用没有参数的函数(我不知道该怎么做)。

2) 我试过thread 接收模板参数但没有成功。

我正在尝试与下面的示例几乎相同(此适配器不适用于没有参数的函数):

typedef void (*WorkerFunPtr)(const std::string&);

template<typename FunT, typename ParamT>
struct Adapter {
    Adapter(FunT f, ParamT& p) : f_(f), p_(&p) {}

    void operator( )( ) {
        f_(*p_);
    }
    private:
    FunT f_;
    ParamT* p_;
};

void worker(const std::string& s) { std::cout << s << '\n'; }

int main( ) {
    std::string s1 = "This is the first thread!";
    boost::thread thr1(Adapter<WorkerFunPtr, std::string>(worker, s1));

    thr2.join( );
}

【问题讨论】:

  • 试试:thread&lt;adapter&lt;thread_func_t&gt; &gt; t_a((adapter&lt;thread_func_t&gt;(&amp;show_hello)));(注意多余的括号。)
  • 我认为你应该通过这种类型传递线程函数typedef void (*thread_func)(void*);

标签: c++ templates compiler-errors adapter functor


【解决方案1】:

这是Most Vexing Parse 问题。您需要在构造函数参数周围添加另一对括号,否则该行将被视为函数声明。

thread<adapter<thread_func_t> > t_a((adapter<thread_func_t>(&show_hello)));

另外,请考虑使用boost::thread,因为它会将您的代码变成三行代码。

【讨论】:

  • 谢谢,您的建议使编译器满意。关于adapter,我声明了两种类型,一种接收参数,另一种不接收(这不是我想要的,但它有效)。
【解决方案2】:

为了完整起见,解决这个棘手问题的另一种方法是先创建一个适配器实例,然后在构造过程中将其传递给您的线程类:

adapter<thread_func_t> some_adapter_delegate_thingy(&show_hello);
thread<adapter< thread_func_t> > t_a(some_adapter_delegate_thingy);

【讨论】:

    【解决方案3】:

    使用统一的初始化语法“{}”

    thread<adapter<thread_func_t> > t_a{adapter<thread_func_t>(&show_hello)};
    

    避免了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多