简体   繁体   English

错误C2783:'_Ty && std :: forward(remove_reference <_Ty> :: type &&)throw()':无法推断'_Ty'的模板参数

[英]error C2783: '_Ty &&std::forward(remove_reference<_Ty>::type &&) throw()' : could not deduce template argument for '_Ty'

I have a templated implementation of a concurrent queue that has a push function that looks like: 我有一个带有push函数的并发队列的模板化实现,如下所示:

template <typename T>
class concurrent_queue
{
public:

    // other code...

    void push(const T& item)
    {
        std::unique_lock<std::mutex> mlock(mutex);
        queue.push_back(std::forward(item));
        mlock.unlock();
        notEmpty.notify_one();
    }

private:

    std::deque<T>               queue;
    std::mutex                  mutex;
    // other stuff...
};

Later on, I instantiate it and use it like so: 稍后,我实例化它并像这样使用它:

concurrent_queue<c2Type> m_queue;  // c2 type is some struct declared previously

and then I try to push items on the queue and I get the afore mentioned compiler error: 然后我尝试推送队列上的项目,我得到上面提到的编译器错误:

c2Type c2message;

// fill in the message struct...
m_queue.push(c2message);

I've sucessfully used the queue before as part of a thread pool implementation where it stored std::function objects. 我之前成功地使用了队列作为线程池实现的一部分,它存储了std::function对象。 I don't understand why it can't deduce the type in this case. 我不明白为什么在这种情况下不能推断出类型。 Any thoughts? 有什么想法吗?

Value categories like "lvalue" and "rvalue" are properties of expressions. 像“左值”和“右值”这样的值类别是表达式的属性。 Expressions that name variables are always lvalue-expressions, even if they name a variable that has the type rvalue reference to some_type . 名称变量的表达式总是lvalue表达式,即使它们命名的变量具有some_type的类型rvalue引用

We use lvalue-reference and rvalue-references to bind different categories of expressions: Per convention, we treat lvalue-references as being bound to lvalues , and rvalue-references as being bound to rvalues . 我们使用lvalue-reference和rvalue-references来绑定不同类别的表达式:按照惯例,我们将lvalue-references视为绑定到lvalues ,并将rvalue-references视为绑定到rvalues

std::forward is intended to restore the value category of what we assume a reference refers to. std::forward旨在恢复我们假设引用所引用的值类别。 For example: 例如:

int   i = 42;
int&  l = i;
int&& r = 21;

l // this expression is an lvalue-expression
r // this expression is an lvalue-expression, too (!)

std::forward<int& >(l) // this function-call expression is an lvalue-expression
std::forward<int&&>(r) // this function-call expression is an rvalue-expression

std::forward , being "an ordinary function", cannot restore the value category merely by using the argument. std::forward ,是“普通函数”,不能仅仅通过使用参数来恢复值类别。 Both arguments are lvalue-expressions. 两个参数都是左值表达式。 You have to specify which value category you want to restore by manually supplying the template-argument. 您必须通过手动提供template-argument来指定要还原的值类别。

This makes only sense if we have a reference where we don't know a priori whether it's an rvalue-reference or an lvalue-reference. 只有当我们有一个我们不知道先验的参考是否是右值参考或左值参考时,这才有意义。 That is the case when writing a function that uses perfect forwarding with forwarding references . 编写使用带转发引用的 完美转发的函数时就是这种情况。

By the way, we want to restore the value category to allow another function to move from the argument we have received. 顺便说一句,我们想要恢复值类别,以允许另一个函数从我们收到的参数移开。 If we receive an rvalue argument, we want to pass on an rvalue, to allow the called function to move. 如果我们收到一个rvalue参数,我们想传递一个rvalue,以允许被调用的函数移动。


For a function like the one in the OP: 对于像OP中那样的函数:

void push(const T& item)

We know that item has the type lvalue reference to const T . 我们知道, item的类型是左值参考const T Therefore, we don't need std::forward : 因此,我们不需要std::forward

void push(const T& item) {
    // ...
    queue.push_back(item); // pass the lvalue argument as an lvalue
    // ...
}

If we add another overload: 如果我们添加另一个重载:

void push(T&& item)

we still don't need std::forward , since the type of that parameter item is always rvalue-reference to T (assuming T is not a reference type) : 我们仍然不需要std::forward ,因为该参数item的类型总是rvalue-reference to T (假设T不是引用类型)

void push(T&& item) {
    // ...
    queue.push_back(std::move(item)); // pass the rvalue argument as an rvalue
    // ...
}

Only if we have something like 只有我们有类似的东西

template<typename U>
void push(forwarding_reference<U> item)

where forwarding_reference<U> can be either an lvalue-reference or an rvalue-reference , then we need std::forward : 其中forwarding_reference<U>可以是左值引用右值引用 ,那么我们需要std::forward

template<typename U>
void push(forwarding_reference<U> item) // not C++, read on
{
    // ...
    queue.push_back(std::forward<U>(item)); // pass lvalue arguments as lvalues
                                            // and rvalue arguments as rvalues
    // ...
}

Due to implementation details, we must write the above as: 由于实施细节,我们必须将上述内容写成:

template<typename U>
void push(U&& item) {
    // ...
    queue.push_back(std::forward<U>(item)); // pass lvalue arguments as lvalues
                                            // and rvalue arguments as rvalues
    // ...
}

Note that the above U&& item is not an rvalue-reference, but a forwarding reference. 请注意,上面的U&& item 不是 rvalue-reference,而是转发引用。 To get a forwarding reference, you need to have a function template with some template type parameter X and a function parameter of the form X&& x . 要获得转发引用,您需要一个带有一些模板类型参数X的函数模板和一个X&& x形式的函数参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误C2783:无法推断出结构参数的模板参数 - error C2783: could not deduce template argument for structure argument std :: forward如何推断出`_Ty`的类型? - How does std::forward deduce the type of `_Ty`? 错误C2782:&#39;const _Ty&std :: min(const _Ty&,const _Ty&)&#39;:模板参数&#39;_Ty&#39;不明确 - error C2782: 'const _Ty &std::min(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous C2783:无法推断帮助器 function 的模板参数 - C2783: Could not deduce template argument for a helper function 错误C2783无法推断模板参数 - error C2783 Could not deduce template arguments 奇怪的模板错误:错误C2783:无法推断模板参数 - Strange Template error : error C2783: could not deduce template argument 错误C2893:无法专门化功能模板&#39;unknown-type std :: less <void> :: operator()(_ Ty1 &amp;&amp;,_ Ty2 &amp;&amp;)const&#39; - error C2893: Failed to specialize function template 'unknown-type std::less<void>::operator ()(_Ty1 &&,_Ty2 &&) const' &#39;std :: map&#39;:&#39;SomeClass&#39;不是参数&#39;_Ty&#39;的有效模板类型参数 - 'std::map' : 'SomeClass' is not a valid template type argument for parameter '_Ty' `std::shared_ptr`:不是参数 `_Ty` 的有效模板类型参数 - `std::shared_ptr`: is not a valid template type argument for parameter `_Ty` 不能将模板参数替换为类型模板参数_Ty - Cannot substitute template argument this for type template parameter _Ty
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM