Возможно ли std :: remove_if с лямбда-предикатом и автоэлементом? - PullRequest
6 голосов
/ 14 июня 2011

Я предполагаю, что это невозможно, потому что я получил следующую ошибку:

error C3533: 'auto': a parameter cannot have a type that contains 'auto'

Вот фрагмент кода для воспроизведения ошибки:

int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
    std::remove_if(myVec.begin(), myVec.end(),
        [](auto i){return i==3;}), // lambda param error
    myVec.end());

Теперь, если вы напишите это, все в порядке, и он сотрет элементы со значением 3:

int myInts[] = {1,2,3,3,3,4};
std::vector<int> myVec(myInts, myInts + sizeof(myInts)/sizeof(int));
myVec.erase(
    std::remove_if(myVec.begin(), myVec.end(),
        [](int i){return i==3;}),
    myVec.end());

Так вы можете просто не использовать auto в качестве параметра функции, как предполагает ошибка?

Это потому, что тип auto определяется значением r * , которое компилятор не может вывести, несмотря на то, что он является предикатом алгоритма, выполняемого для известного вектора int?

Кто-нибудь знает причину?

Ответы [ 3 ]

8 голосов
/ 14 июня 2011

К сожалению, хотя это было предложено во время процесса C ++ 0x, в конечном итоге это никогда не было сделано. Для простых функторов вы можете использовать что-то вроде Boost.Lambda (возможно, Phoenix v3, когда он выйдет тоже),где генерируемые функторы полиморфны (и, следовательно, вам не нужно ничего указывать):

std::remove_if(myVec.begin(), myVec.end(),
    _1 == 3)

Решение только с выводом типа:

// uses pass-by-reference unlike the question
std::remove_if(myVec.begin(), myVec.end(),
    [](decltype(myVec[0]) i){return i==3;})
8 голосов
/ 14 июня 2011

auto - это вывод типа, основанный на значении, к которому вы его инициализируете. Параметр ни к чему не инициализируется в том месте, в котором он указан в коде.

2 голосов
/ 14 июня 2011

По сути, это уже было предложено, затем отклонено, и затем лямбды были добавлены, так что это почти почти вошло, но не произошло, и очень вероятно, что это будет сделано в языке вбудущее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...