2014-09-11 3 views
2

У меня есть std :: multiset, в котором хранится std :: pair. Я хочу, чтобы у первого атрибута не было ограничений на уникальность, но я хочу, чтобы второй был уникальным. Итак, я решил передать свою собственную функцию в мультимножество, чтобы добиться этого (если не сообщите мне).Передача моей функции сравнения в std :: multiset с C++ 11

На основании this Ответ, я написал аналогичную функцию, но это не удается, и я понятия не имею, почему (нет идеи λ - и я греческий :)).

auto f = [](std::pair<float, int>& a, std::pair<float, int>& b) { 
    return (a.first < b.first && a.second != b.second); 
}; 

Ошибка:

error: expression ‘#‘lambda_expr’ not supported by dump_expr#<expression error>’ is not a constant-expression 
sorry, unimplemented: non-static data member initializers 
error: unable to deduce ‘auto’ from ‘<expression error>’ 
+0

Это означает, что я на ложном пути @TC . Что мне делать? – gsamaras

+0

Я не понимаю ваш критерий уникальности. Вы используете «multiset», поэтому в контейнере будут храниться несколько ключей, которые сравнивают одинаковые значения. – Praetorian

+1

Я думаю, что главная проблема заключается в том, что лямбда нужно принимать 'const &' или по значению –

ответ

3

Я думаю, что вы не можете передать лямбда (во время выполнения конструкции) в качестве параметра шаблона (время компиляции конструктов). Используя-структуру с operator() работает вместо:

#include <set> 
struct my_compare { 
    bool operator() (const std::pair<float, int>& a, const std::pair<float, int>& b) { 
    return (a.first < b.first && a.second != b.second); 
    }; 
}; 
int main(int argc, char ** argv) { 
    std::multiset<std::pair<float, int>, my_compare> set; 
    return 0; 
} 

Или, с лямбда и decltype (как в ответ преторианской в):

#include <set> 
int main(int argc, char ** argv) { 
    auto my_compare = [](const std::pair<float, int>& a, const std::pair<float, int>& b) { 
    return (a.first < b.first && a.second != b.second); 
    }; 
    std::multiset<std::pair<float, int>, decltype(my_compare)> set(my_compare); 
    return 0; 
} 
+0

У меня есть другая ошибка, чем вы видите, на GCC 4.9: темп.cpp: 13: 40: error: аргумент шаблона для параметра типа шаблона должен быть типом. – Zach

+0

Парень в ссылке, которую я предложил, предположил, что с λ. Добавьте 'set.insert (std :: make_pair (0.1, 1));' чтобы посмотреть, что это произойдет. Был комментарий от @ T.C. заявив, что мультимножество требует сильного заказа, которого нет у нашего сравнения! – gsamaras

+0

По-видимому, причина, по которой вызов insert() терпит неудачу, заключается в том, что компилятор недоволен тем, что параметры не являются константами. Я уточню свой ответ. – Zach

5

Поскольку вы используете multiset, а не set, многократная ключи, сравнивающие одинаковые, все равно будут храниться в контейнере, поэтому я не уверен, что вы имеете в виду, когда говорите об уникальности.

Предполагая, что вы означало, что вы хотите только второй элемент в pair влиять на заказ, вы можете использовать лямбда следующим образом:

auto f = [](std::pair<float, int> const& a, std::pair<float, int> const& b) { 
    return a.second < b.second; 
}; 
std::multiset<std::pair<float, int>, decltype(f)> m(f); 

Live demo

+0

Спасибо, я отвечу на другой ответ, потому что он пришел первым и для честной игры. :) – gsamaras

+1

@ G.Samaras Вы принимаете лучший ответ, здесь нет никакой честной игры. Мы не играем в игру. Те, кто используют SO для получения репутации вместо знания, являются дураками. – 101010

+0

Хорошая точка @ 40two. Я все равно оставлю другой ответ, потому что это было сначала. :) – gsamaras