为什么我不能在C ++中将特征与转发引用一起使用? [英] Why can't I use traits with forwarding references in C++?

查看:66
本文介绍了为什么我不能在C ++中将特征与转发引用一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试代码。

请参阅godbolt https://godbolt.org/z/fLRM8d (作为可执行示例)

See godbolt https://godbolt.org/z/fLRM8d for an executable example

template <typename T> struct Traits {
    static const bool value = false;
};

struct Zip{};
template <> struct Traits<Zip> {
    static const bool value = true;
};

template <typename E>
void Execute(E && e){
    static_assert(Traits<E>::value);
}

int main(){

    auto z = Zip();

    // Fails the static assertion with an lvalue
    Execute(z);

    // Passes the static assertion with an rvalue
    Execute(Zip());
}

这里发生了什么事,我无法使用自己的类型特征期望?为这个问题建模的正确方法是什么?

What is going on here that I can't use my type trait as I expect? What is the correct way to model this problem?

推荐答案

在标准中有一个特殊的规则可以推论转发引用。给定转发参考参数 T& ,将推导 T 作为左值参考如果使用 lvalue 调用该函数。

There is a special rule regarding deduction of forwarding references in the Standard. Given a forwarding reference parameter T&&, T will be deduced as an lvalue reference if the function is called with an lvalue.

您需要在特征中考虑这一点:

You need to take this into account in your traits:

Traits<std::remove_reference_t<E>>::value

godbolt.org上的实时示例

根据标准:

http://eel.is/c++draft/temp.deduct.call#3


转发引用是对不代表类模板的模板参数的cv不合格模板参数的右值引用(在类模板参数推导([over.match.class.deduct]期间))。如果P是转发引用,并且参数是左值,则使用类型对A的左值引用代替A进行类型推导。

A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template (during class template argument deduction ([over.match.class.deduct])). If P is a forwarding reference and the argument is an lvalue, the type "lvalue reference to A" is used in place of A for type deduction.

这篇关于为什么我不能在C ++中将特征与转发引用一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆