Неясное поведение шаблонов

123
28 апреля 2019, 18:20

Есть следующая шаблонная функция:

template<class func, class ...Args>
auto func_wrapper_to_bool(func &&_Fn, Args &&... args)
{
    if constexpr (std::is_member_function_pointer<func>::value)
        return func_wrapper_to_bool(std::mem_fn(std::forward<func>(_Fn)), std::forward<Args>(args)...);
    else
    {
        if constexpr (std::is_same<decltype(_Fn(std::forward<Args>(args)...)), bool>::value)
            return [&]()->bool {return _Fn(std::forward<Args>(args)...); };
        else
            return [&]()->bool {_Fn(std::forward<Args>(args)...); return true; };
    }
}

В моём коде она требуется для того, чтобы обернуть любую функцию, которая возвращает не bool в функцию которая возвращает bool

У меня есть класс

class Test
{
public:
    void switcher(int i)
    {
        std::cout << i << std::endl;
        std::cout << "Cool!!!" << std::endl;
    }
}; 

В функции main я вызываю функцию следующим образом:

int main()
{
    Test ts;
    auto mem_fn = func_wrapper_to_bool(std::mem_fn(&Test::switcher), ts, 1);
    mem_fn();
    auto not_mem_fn = func_wrapper_to_bool(&Test::switcher,ts,2);
    not_mem_fn();
}

При компиляции релиз версии программа отлично отрабатывает, а при компиляции дебаг версии вылетает при вызове оператора() у not_mem_fn. С чем это может быть связанно ?

Answer 1

Ну так ваш внутренний

std::mem_fn(std::forward<func>(_Fn))

это временный объект, который заведомо будет уничтожен еще до выхода из вашего func_wrapper_to_bool. А вы его захватываете по ссылке в лямбду.

Потом при вызове через not_mem_fn, возвращенного из func_wrapper_to_bool, лямбда обращается к этому объекту через ссылку, а он уже уничтожен. Та же проблема имеет место и с первым вызовом - переданный снаружи временный std::mem_fn(&Test::switcher) тоже уничтожается еще до вызова вашего mem_fn().

И с аргументами та же проблема. В момент вызова func_wrapper_to_bool значения 1 и 2 существуют только в виде временных объектов. Лямбда захватывает их по ссылке, а к моменту фактических вызовов они уже уничтожены.

READ ALSO
(C++) Как заблокировать перемещение мыши?

(C++) Как заблокировать перемещение мыши?

делаю внутри игровое меню и столкнулся с проблемой, как заблокировать мышь?

118
GNU Make C++. Linux

GNU Make C++. Linux

Возможно, не совсем понимая что искать, не могу найти действующего примераПроект на C++, разбит на подпапки(src:Engine{Component, Utils}, Process{Objects,

166
Сложение volatile - UB?

Сложение volatile - UB?

Содержит ли следующая программа UB?

129