Вопрос:

Почему нельзя связать const char * lvalue с const char * const &&?

c++ templates c++11

772 просмотра

2 ответа

8 Репутация автора

Я делаю упражнения на «C ++ Primer 5th» ex16.63 и 64, и описание этих упражнений следующее.

Упражнение 16.63: определение шаблона функции для подсчета количества вхождений данного значения в векторе. Протестируйте вашу программу, передав ей вектор чисел типа double, вектор чисел и вектор строк.

Упражнение 16.64. Написание специализированной версии шаблона из предыдущего упражнения для обработки вектора и программы, использующей эту специализацию.

Вот мой код:

#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верен.

Автор: Wiesen Источник Размещён: 12.02.2015 04:41

Ответы (2)


3 плюса

137661 Репутация автора

Решение

Lvalues ​​не может привязываться к ссылкам rvalue. Это общее правило. Как таковой, он распространяется на все типы, в том числе const char*.

Причина того, что ваш код для 16.63 работает, заключается в том, что вы передаете rvalue в: 1и 3.14являются rvalues, потому что они не строковые литералы. std::string("python")это значение, потому что это временно.

pс другой стороны, является lvalue.

Автор: Angew Размещён: 12.02.2015 04:47

0 плюса

1 Репутация автора

Вы можете попробовать это вместо этого:

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

Функция std :: move возвращает значение r. Код запускается и производит:

1 2 2
2
Автор: Raisin Ten Размещён: 13.06.2019 06:21
Вопросы из категории :
32x32