为什么我不能在 C++ 中使用带有转发引用的特征?
Why can't I use traits with forwarding references in C++?
我有以下测试代码。
有关可执行示例,请参阅 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());
}
这是怎么回事,我不能像我期望的那样使用我的类型特征?对这个问题建模的正确方法是什么?
标准中有一条关于扣除转发引用的特殊规则。给定转发引用参数 T&&
,如果使用 lvalue[=29= 调用函数,T
将被推断为 lvalue reference ].
你需要在你的特质中考虑到这一点:
Traits<std::remove_reference_t<E>>::value
来自标准:
http://eel.is/c++draft/temp.deduct.call#3
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.
我有以下测试代码。
有关可执行示例,请参阅 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());
}
这是怎么回事,我不能像我期望的那样使用我的类型特征?对这个问题建模的正确方法是什么?
标准中有一条关于扣除转发引用的特殊规则。给定转发引用参数 T&&
,如果使用 lvalue[=29= 调用函数,T
将被推断为 lvalue reference ].
你需要在你的特质中考虑到这一点:
Traits<std::remove_reference_t<E>>::value
来自标准:
http://eel.is/c++draft/temp.deduct.call#3
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.