模板成员函数错误:clang与任何成员函数都不匹配

时间:2013-05-17 20:31:31

标签: c++ templates c++11 clang

我编写了以下模板成员函数,但我不能在没有编译器错误的情况下调用它:

template <class T, class A>
auto tpool::enqueue(T&& func, std::vector<A>&& args)
-> std::vector<std::future<decltype(std::forward<T>(func)(decltype(std::forward<A(args))::value_type))>>
{
    //...
}

tpool tp();
auto f = [] (int) { /* ... */ };
std::vector<int> args; 

tp.enqueue(f, args);

我通过clang得到以下错误:

test_cpp.cpp:144:5: error: no matching member function for call to 'enqueue'
    tp.enqueue(f, args);

test_cpp.cpp:107:13: note: candidate template ignored: substitution failure [with T = <lambda at test_cpp.cpp:140:11> &, A = int]: no matching function for call to 'forward'
auto tpool::enqueue(T&& func, std::vector<A>&& args)

1 个答案:

答案 0 :(得分:2)

template <class T, class A>
auto tpool::enqueue(T&& func, std::vector<A>&& args)

这使得args成为右值引用,仅接受rvalue,但在

std::vector<int> args; 
tp.enqueue(f, args);

args是一个左值,因此候选词被忽略。

请注意T&& func允许绑定左值,因为模板替换可以允许T本身为左值引用,然后我们有(T&)&& == T&。但args无法做到这一点,因为无论A是什么,std::vector<...>&&始终是向量的右值引用。


如果你不打算复制或修改args,你可以改为传递const引用:

template <class T, class A>
auto tpool::enqueue(T&& func, const std::vector<A>& args)

您还可以通过不指定args必须是向量来允许完美转发:

template <class T, class V>
auto tpool::enqueue(T&& func, V&& args)
    -> std::vector<std::future<decltype(func(args.front()))>>