Показаны сообщения с ярлыком auto. Показать все сообщения
Показаны сообщения с ярлыком auto. Показать все сообщения

пятница, 5 октября 2018 г.

Указатель на нестатическую функцию-член класса / non-static function member pointer

Отличий от обычного указателя на фунцию только два: как объявлять и как вызывать. Лучше всего пояснить на примере:


#include <iostream>
#include <string>

class MyClass
{
public:
    MyClass(int i) : m_i(i) {}
    void func() { std::cout << "m_i = " << m_i << "\n"; }

private:
    int m_i;
};

int main()
{
    MyClass obj1(1);
    MyClass obj2(2);
    void (MyClass::*fptr)() = &MyClass::func; // define and initialize function pointer
    obj1.func();
    ((&obj2)->*fptr)(); // use function pointer via an object pointer
}

Однако, с помощью более свежих версий C++ это можно упростить:


#include <iostream>
#include <string>

class MyClass
{
public:
    MyClass(int i) : m_i(i) {}
    void func() { std::cout << "m_i = " << m_i << "\n"; }

private:
    int m_i;
};

int main()
{
    MyClass obj1(1);
    MyClass obj2(2);
    auto fptr = &MyClass::func; // define and initialize function pointer
    obj1.func();
    ((&obj2)->*fptr)(); // use function pointer via an object pointer
}

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

пятница, 20 апреля 2018 г.

Поиск функцией std::find_if по ассоциативному спику std::map / Searching by std::find_if on std::map

Иногда надо перебрать все элементы ассоциативного списка и можно это сделать традиционно, с помощью цикла for.
Но есть более изящное решение с использованием возможностей C++11. Допустим у нас есть ассоциативный список типа  std::unordered_map<int, MyType>.
Вот как это можно сделать:

// very clear lambda statement
auto pred = [sVal](const std::pair<int, MyType>& x) { return x.second.val == sVal; }; 
const auto it = std::find_if(myMap.begin(), myMap.end(), pred);

Но есть один недостаток: надо явно указывать тип элемента контейнера, который мы перебираем, в лямбда-выражении. Но можно сделать так, чтобы компилятор сам определал это:

// does the same, but looks much smarter ^_^
auto pred = [sVal](const decltype(myMap.begin())::value_type& x) { return x.second.val == sVal; }; 
const auto it = std::find_if(myMap.begin(), myMap.end(), pred);

Получилось боле громоздко, но зато более универсально.