14

我正在使用 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() 触发的,我用它来捕捉将访问者应用于不良变体类型的尝试。

4

6 回答 6

1

为什么要为模板运算符提供一个主体?

我这里没有方便的 Boost,所以我无法为您检查,但是模板化运算符具有主体这一事实很可能意味着任何和所有调用,无论类型如何,都可以正常编译,然后在运行时抛出错误.

将模板操作符的主体排除在外,当与除 double 之外的任何其他类型一起使用时,它将简单地拒绝链接。

于 2011-04-04T20:03:38.000 回答
1

在吃了一顿午餐和散步之后,我有一个不满意但有效的解决方法。我没有从访问者那里返回一个变体并引发错误,而是返回一个成功布尔值并存储一个结果,因此:

#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;
}
于 2011-04-01T13:21:13.593 回答
1

#pragma 不起作用,因为这是链接时间而不是编译时间警告。

您可以在发布模式下抑制警告。我相信链接器命令行上的 /ignore:xxxx 可以解决问题。

于 2011-04-05T17:44:33.683 回答
1

我在 Visual Studio 2012 MFC 项目中遇到了非常相似的问题;同样的警告来自<memory>头文件,也在发布链接时间代码生成期间。
我通过 在预编译头文件的早期添加#pragma warning(disable:4702)解决了这个问题(在我的例子中是“stdafx.h” ,就在#include STL 头文件之前)。

于 2013-09-27T13:39:08.353 回答
0

如果我声明了非双精度方法但不提供实现,那么我会收到“未解决的外部”链接器错误。

尝试inline在模板运算符定义中添加说明符。那么 MSVC 不应该需要它的主体来编译类本身。因此,unresolved external只有当您的代码尝试使用此模板时,您才会收到编译时错误。据我了解 - 这正是你想要的。

于 2011-04-05T19:03:29.103 回答
0

将模板设为operator()(...)私有,不提供实现。这将在编译时而不是链接时使用它。

于 2011-04-05T19:41:36.953 回答