提问人:f1msch 提问时间:6/23/2022 最后编辑:Evgf1msch 更新时间:6/23/2022 访问量:156
为什么通用引用作为输入参数不起作用
Why universal reference as an input parameter doesn't work
问:
template<typename T>
constexpr auto log_value(T&& value) {
if constexpr (std::is_enum_v<T>) {
cout << "enum" << endl;
}
else {
cout << "normal" << endl;
}
}
我有一个函数来判断某个值是否是枚举,我通过以下方式对其进行测试
enum class A {
a,
s,
d
};
int main() {
auto s = A::a;
const auto& s1 = s;
auto&& s2 = A::a;
log_value(s);
log_value(s1);
log_value(s2);
log_value(A::a);
但结果是
normal
normal
normal
enum
当我把它改成:
template<typename T>
constexpr auto log_value_const_left(const T& value) {
if constexpr (std::is_enum_v<T>) {
cout << "enum" << endl;
}
else {
cout << "normal" << endl;
}
}
它有效
enum
enum
enum
enum
现在我只是想知道为什么不起作用?输入参数中的输入参数不是可以引用左值引用或右值引用吗?log_value
T&& value
log_value
如果在,它到底是什么?为什么它仍然被改变?std::is_enum_v<T> != true
log_value
答:
8赞
HolyBlackCat
6/23/2022
#1
转发(又称通用)引用对左值的工作方式是将引用类型(在您的情况下)推导为左值引用(在您的情况下)。然后也变成根据参考折叠规则 ( + = )。T
A &
T &&
A &
&
&&
&
对于右值,这不是必需的,并且被推导出为非引用。T
你想要。std::is_enum_v<std::remove_reference_t<T>>
评论
0赞
f1msch
6/23/2022
哇~~ 但是为什么(以左值引用为指向)不起作用?[en.cppreference.com/w/cpp/types/is_enum]似乎没有提到它。std::is_enum_v<T>
1赞
HolyBlackCat
6/23/2022
@f1msch 因为那是引用而不是枚举?通常,这些特征会忽略 cv 限定符(即 const 和 volatile),但不会忽略 reference-ness。is_...
0赞
Prof.
6/23/2022
#2
如果您使用 std::forward,则可以使用您的第一个版本。
enum class A {
a,
s,
d
};
int main() {
auto s = A::a;
const auto& s1 = s;
auto&& s2 = A::a;
log_value(std::move(s));
log_value(std::move(s1));
log_value(std::move(s2));
log_value(A::a);
}
但是 std::remove_reference_t 或 c++20 中的 std::remove_cvref 是你要走的路。
评论