14

我使用boost :: variant,并且在发布模式下编译时遇到问题。我在VC2010中工作,警告级别为4,警告为错误。下面的代码在调试模式下编译得很好,但是在发布模式下,我得到了一堆链接时发出的“无法到达的代码”C4702警告(大概我在这里收到编译器警告,因为启用优化时会生成链接时间代码。)有没有解决此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; 
} 

警告是由模板运算符(),我使用的是赶上尝试访问者适用于恶劣变异类型的触发。

+5

大拇指! – 2011-04-01 12:26:40

+0

您是否尝试过把编译在文件的顶部,包括前?并且@Matthieu绝对会在它们显示之前杀死错误 – ssube 2011-04-04 20:19:34

+1

我曾尝试在文件顶部,类定义周围,apply_visitor调用周围以及stdafx.h顶部放置编译指示。工作,不幸的是, – RobH 2011-04-05 07:15:36

回答

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; 
} 
1

为什么对模板操作者提供一个身体呢?

我还没有在这里获得Boost方便所以我不能检查你,但事实上模板操作员有一个身体最有可能意味着任何和所有调用,无论类型,将编译罚款,然后抛出运行时出错。

将模板运算符的主体留出,并且在使用任何其他类型而不是双精度值时,它将拒绝链接。

+0

问题是变体的类型是在运行时确定的。在这种情况下,变体实际上拥有市场数据流中的值,并且值(以及它们的类型)的选择是可配置的。例如,这个访问者类可能被应用于包含null和double的变体,我需要捕获它。编译器期望变体模板参数列表中的每对类型都有一个有效的operator();如果我声明非double方法但不提供实现,那么我会得到一个“无法解析的外部”链接器错误。 – RobH 2011-04-05 07:28:13

1

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

您可以在发布模式下抑制警告。我相信/忽略:在链接器命令行上的xxxx会执行这个技巧。

+1

不幸的是,忽略链接器错误的选项已从VC2010中删除。此外,这实际上是一个编译器警告,由链接时代码生成生成(我认为)。 – RobH 2011-04-08 09:04:31

0

如果我宣布非双重​​方法,但 不提供实现,那么我 得到一个“无法解析的外部”链接 错误。

尝试在模板操作符定义处添加inline说明符。然后MSVC不应该需要它的主体编译类本身。因此,而不是unresolved external只有当您的代码尝试使用此模板时,才会收到编译时错误。据我所知 - 这正是你想要的。

+0

您可能会被我简化的示例代码误导。实际上,在编译时我不知道我的变体的类型。它们包含活饲料的价格,其中一些可能是双倍的,一些为零。类型检查是在运行时,所以在编译时我需要(boost :: variant实现,因此编译器要求)访问方法的实现,以实现包含类型的所有可能组合。 – RobH 2011-04-08 09:02:30

0

使模板operator()(...)为私人并且不提供实施。这将在编译时捕获它的使用,而不是链接时间。

+0

变体类型检查在运行时(请参阅我的评论和其他地方的答案),因此未能提供实现不起作用。 – RobH 2011-04-08 09:03:28

1

我在Visual Studio 2012 MFC项目中遇到了非常类似的问题;同样的警告来自<内存>头文件,也在版本链接时间码生成。
我解决了这个问题,在预先编译的头文件(“stdafx”)中加入#pragma warning(disable:4702)。H”于我而言,只是之前#包括 STL头文件)。弥补警告级别4 +警告视为错误