为什么我不能在C ++中将特征与转发引用一起使用?

时间:2018-12-12 11:28:29

标签: c++ c++11 typetraits perfect-forwarding

我有以下测试代码。

有关可执行示例,请参见Godbolt https://godbolt.org/z/fLRM8d

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());
}

这是怎么回事,我无法按预期使用类型特征?为该问题建模的正确方法是什么?

1 个答案:

答案 0 :(得分:7)

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

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

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

live example on godbolt.org


根据标准:

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

  

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