为什么通用引用作为输入参数不起作用

f1m*_*sch 2 c++ pass-by-reference rvalue-reference c++17

template<typename T>
constexpr auto log_value(T&& value) {
    if constexpr (std::is_enum_v<T>) {
        cout << "enum" << endl;
    }
    else {
        cout << "normal" << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个函数来判断某个值是否是枚举,我通过以下方式测试它

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);
Run Code Online (Sandbox Code Playgroud)

但结果是

normal
normal
normal
enum
Run Code Online (Sandbox Code Playgroud)

当我将其更改为:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

有用

enum
enum
enum
enum
Run Code Online (Sandbox Code Playgroud)

现在我只是想知道为什么log_value不起作用?不是称为通用引用T&& value中的输入参数log_value可以引用左值引用或右值引用吗?

如果std::is_enum_v<T> != truelog_value,它到底是什么?怎么还是变了?

Hol*_*Cat 8

左值转发(也称为通用)引用的方式是将引用类型(T在您的情况下)推导为左值引用(A &在您的情况下)。然后也根据参考折叠规则(+ = )T &&变成。A &&&&&

对于右值来说,这是不需要的,并且T被推导为非引用。

你要std::is_enum_v<std::remove_reference_t<T>>