为什么不能将“const char*”右值绑定到“const char* const”?

Why cannot bind ‘const char*’ lvalue to ‘const char* const&&?

我正在做"C++ Primer 5th"ex16.63和64的练习,下面是关于这些练习的说明。

练习 16.63:定义一个函数模板来计算给定值在向量中出现的次数。通过向程序传递一个双精度向量、一个整数向量和一个字符串向量来测试您的程序。

练习 16.64:从 之前处理 vector< const char* > 的练习和一个程序 使用此专业。

这是我的代码:

#include <iostream>
#include <vector>
#include <string>

// ex16_63
template<typename T>
std::size_t VecCount(const std::vector<T> &vec, const T &&val){
    std::size_t num = 0;
    for(auto i: vec){
        if(val == i) ++num;
    }
    return num;
}

//ex16_64
template<>
std::size_t VecCount(const std::vector<const char*> &vec, const char* const &&val){
    std::size_t num = 0;
    for(auto i: vec){
        if(val == i)++num;
    }
    return num;
}

int main()
{
    // ex16_63
    std::vector<int> nVec = {1, 2, 3};
    std::vector<double> dVec = {3.14, 2.24, 3.14};
    std::vector<std::string> sVec = {"hello", "python", "python"};
    std::cout << VecCount(nVec, 1) << ' '
              << VecCount(dVec, 3.14) << ' '
              << VecCount(sVec, std::string("python")) << std::endl;

    // ex16_64
    std::vector<const char*> cVec = {"world", "turing", "turing"};
    const char *p = "turing";
    std::cout << VecCount(cVec, p) << std::endl; // wrong
    //std::cout << VecCount(cVec, std::move(p)) << std::endl; // correct
    return 0;
}

编译时出错ex16_64:

error: cannot bind ‘const char*’ lvalue to ‘const char* const&&’ std::cout << VecCount(cVec, p) << std::endl;

我不明白我关于 ex16_64 的代码没有 std::move 是错误的,而我关于 ex16_63 的代码是正确的。

左值不能绑定到右值引用。这是一般规则。因此,它适用于所有类型,包括 const char*.

您的 16.63 代码有效的原因是您恰好传递了右值:13.14 是右值,因为它们是非字符串文字。 std::string("python") 是一个右值,因为它是临时的。

另一方面,

p 是一个左值。

您可以试试这个:

std::cout << VecCount(cVec, std::move(p)) << std::endl;

std::move函数returns一个右值。代码运行并产生:

1 2 2
2