Какой смысл в std :: remove_reference - PullRequest
0 голосов
/ 03 мая 2018

Позвольте мне погрузиться в C ++ 14 общих лямбд с:

#include <iostream>

// g++ -std=c++14 

template<typename T>
T incr(T v)
{
    return v + 1;
}


int main()
{
    float f = 2.0;
    int i = 3;

    auto selfincr = [] (auto & value)
        {
            value = incr<std::remove_reference<decltype(value)>>(value);    // A
            value = incr<decltype(value)>(value);                           // B
        };


    selfincr(f);
    selfincr(i);

    std::cout << "f " << f << ", i " << i << std::endl;
    return 0;
}

Так как строка // B вызывает

недопустимая инициализация неконстантной ссылки типа ‘T &’ из значения типа ‘T’

Моим непосредственным предположением было удаление ссылки, поэтому я добавил строку // A. Но это дает

нет соответствующей функции для вызова ‘incr (T &)’

Так как я могу удалить эту ссылку?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Это:

value = incr<std::remove_reference<decltype(value)>>(value);    // A

не работает из-за того, что songyuanyao объяснил.

<ч />

Это:

value = incr<decltype(value)>(value);                           // B

не работает, потому что decltype(value) является ссылочным типом, и вы пытаетесь создать его экземпляр:

float& incr(float& v) { return v + 1; }
int& incr(int& v) { return v + 1; }

Вы не можете связать эти выражения с неконстантными ссылками lvalue, следовательно, ошибка компиляции.

<ч />

Самое простое решение - просто позволить выводу шаблона сделать свое дело:

value = incr(value); // C

Это вызовет incr<int> и incr<float> по желанию.

0 голосов
/ 03 мая 2018

Так как я могу удалить эту ссылку?

incr<std::remove_reference<decltype(value)>>(value), вы указываете std::remove_reference<T> в качестве параметра шаблона, а не тип, указанный в T (т.е. decltype(value)). То, что вы хотите, должно быть

value = incr<typename std::remove_reference<decltype(value)>::type>(value);    // A
//           ~~~~~~~~                                       ~~~~~~        

А начиная с C ++ 14 вы могли бы упростить его:

value = incr<std::remove_reference_t<decltype(value)>>(value);    // A
//                                ~~ 

ЖИТЬ

...