Есть ли способ обхода этого предупреждения C4702?

Я использую boost:: variant, и у меня проблема с компиляцией в режиме выпуска. Я работаю в VC2010 с предупреждающим уровнем 4 и предупреждениями как ошибки. Код ниже компилируется в режиме отладки, но в режиме выпуска я получаю кучу предупреждений C4702 "Недостижимый код", выпущенных во время ссылки (предположительно, я получаю предупреждения от компилятора здесь, потому что при оптимизации оптимизируется генерация кода времени).

Кто-нибудь успешно отключил эти предупреждения в этой ситуации? Я бы предпочел сохранить высокий уровень предупреждения и предупреждения как возможные ошибки.

#pragma warning( disable:4702 )

... похоже, здесь не работает. Вот пример кода:

#include <boost/variant.hpp>

struct null{};
typedef boost::variant< null, double > variant_t;

class addition_visitor
: public boost::static_visitor< variant_t >
{
public:
    template< typename T, typename U >
    variant_t operator()( const T&, const U& ) const
    { 
        throw( "Bad types" );
    }

    variant_t operator()( const double& left, const double& right ) const
    {
        return variant_t( left * right );
    }
};

int main(int /*argc*/, char** /*argv*/)
{
    variant_t a( 3.0 ), b( 2.0 );
    variant_t c = boost::apply_visitor( addition_visitor(), a, b );
    return 0;
}

Предупреждение запускается шаблоном operator(), который я использую, чтобы поймать попытки применить посетителя к типам плохого варианта.

Ответы

Ответ 1

После пятна ланча и прогулок у меня есть неудовлетворительная, но работающая работа. Вместо того, чтобы возвращать вариант от моего посетителя и бросать на ошибку, я возвращаю успех boolean и сохраняю результат, таким образом:

#include <boost/variant.hpp>

struct null{};
typedef boost::variant< null, double > variant_t;

class addition_visitor
: public boost::static_visitor< bool >
{
public:
    template< typename T, typename U >
    bool operator()( const T&, const U& )
    { 
        //throw( "Bad types" );
        return false;
    }

    bool operator()( const double& left, const double& right )
    {
        result = variant_t( left * right );
        return true;
    }

    variant_t result;
};

int main(int /*argc*/, char** /*argv*/)
{
    variant_t a( 3.0 ), b( 2.0 );
    addition_visitor v;
    if( !boost::apply_visitor( v, a, b ) )
    {
        throw( "Bad types" );
    }

    variant_t c = v.result;
    return 0;
}

Ответ 2

Зачем создавать тело для оператора шаблона?

У меня здесь нет Boost, поэтому я не могу проверить вас, но тот факт, что шаблонный оператор имеет тело, скорее всего, означает, что любые вызовы, независимо от типа, будут компилироваться в порядке, а затем ошибка во время выполнения.

Оставьте тело оператора шаблона, и он просто откажется ссылаться при использовании с любым другим типом, чем double.

Ответ 3

#pragma не работает, потому что это время ссылки, а не предупреждение времени компиляции.

Вы можете подавить предупреждение в режиме деблокирования. Я верю/игнорирую: xxxx в командной строке компоновщика сделает трюк.

Ответ 4

У меня была очень похожая проблема в проекте Visual Studio 2012 MFC; то же предупреждение было получено из <memory> заголовочный файл, также во время генерации кода времени выпуска.
Я решил это, добавив предупреждение #pragma (disable: 4702) в начале предварительно скомпилированного файла заголовка ( "stdafx.h" в моем случае, перед #include заголовочными файлами STL).

Ответ 5

Если я объявляю недвойный метод, но не обеспечивают реализацию, тогда я получить "неразрешенный внешний" компоновщик ошибка.

Попробуйте добавить спецификатор inline в определение оператора шаблона. Тогда MSVC не нуждается в том, чтобы его тело компилировало сам класс. Поэтому вместо unresolved external вы будете получать ошибки во время компиляции только тогда, когда ваш код попытается использовать этот шаблон. Насколько я понимаю - это именно то, что вы хотите.

Ответ 6

Сделать шаблонный operator()(...) закрытый и не предоставлять реализацию. Это позволит использовать его во время компиляции вместо времени ссылки.