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 +警告視爲錯誤