VS2012 std :: function operator bool неожиданно возвращает true

Я столкнулся со странным поведением в VS2012 с std :: function, о котором я ничего не мог найти в Интернете.

Учитывая следующий пример программы:

#include <functional>
#include <iostream>

typedef std::function< int()> fntype;

void foo(const fntype& fn)
{
    try
    {
        if(fn)
            fn();
        else
            std::cout << "fn is empty" << std::endl;
    }
    catch(const std::bad_function_call&)
    {
        std::cout << "fn threw anyways" << std::endl;
    }
}


int main(int argc, char **argv)
{
    // OK
    std::function<int()> nothing;
    foo(nothing);

    // Fails
    std::function<const int()> nothing2;
    foo(nothing2);
    
    return 0;
}

Второй вызов foo () компилируется (даже если константа возвращаемого типа не совпадает с fntype. Однако if (fn) принимает значение true тем не менее.

Результат:

fn пуста

fn все равно бросил

Примечание. В отладчике fn отображается как пустая в обоих случаях.

Такое поведение невозможно воспроизвести с помощью GCC (Coliru). Здесь получается ожидаемый результат:

Результат:

fn пуста

fn пуста

Это проблема в реализации стандартной библиотеки VS2012?

Есть ли способ обойти эту проблему: a) получить значение false для fntype :: operator bool () в случае 2 или b) привести к сбою компиляции из-за несоответствия подписи.


person namezero    schedule 09.03.2015    source источник


Ответы (1)


Похоже, это ошибка 2012 г., а в 2013 г. ее не было. посмотреть вживую это список ошибок: 44 ошибки C ++ 11, также исправленные в Visual Studio 2013 упоминает, что это было исправлено в 2013 году, и говорит:

В некоторых случаях преобразование могло привести к неверному результату в VS2012 из-за того, что объект функции не был пустым, когда он должен быть. Например:

// JetPlane derives from Plane
function<bool(JetPlane*)> plane_ready_func = function<bool(Plane*)>();
if (plane_ready_func)   // should yield false but doesn't
{
    plane_ready_func(nullptr);   // gets called and throws bad_function_call
}

конструктор по умолчанию для std :: function должен создать пустая функция.

Я нашел как минимум один один отчет об ошибке, который соответствует приведенному выше списку ошибок.

person Shafik Yaghmour    schedule 09.03.2015
comment
Спасибо за подтверждение. Я встречал эту страницу раньше, но не связал этот пример с рассматриваемой проблемой. Я приму это как решение, поскольку оно подтверждает мои подозрения. - person namezero; 10.03.2015