![](/img/trans.png)
[英]Error while compiling code having | operator overloaded under template definition ,with VS2017 Update8.2
[英]How to get programatically all the compiler flags set by /permissve- in VS2017 Update8.2
如何以編程方式獲取由Visual Studio 2017編譯器啟用的選項標志/ permissive-
根據Microsoft文檔/ permissive-flag設置/ Zc編譯器選項以實現嚴格一致性
現在,下面的代碼在僅啟用/ permissive-編譯器標志的Visual Studio 2017 Update8.2上進行編譯,並且在未打開/ permissive-標志的情況下失敗(在Vs2017 Update 8.2上)
#include <sstream>
namespace ABC {
template <typename T>
bool operator|(T v1, T v2) {
}}
std::stringstream ss_; //commenting this removes the error
using namespace ABC;
int main() {
return 0;
}
我想知道/ Zc的哪個編譯器標志已修復此問題
如果沒有/permissive-
則會出現此問題,因為編譯器將不會對模板執行正確的兩階段名稱查找。
在sstream的270行中,您將找到:
…
constexpr auto _Both = ios_base::in | ios_base::out;
…
作為std::basic_stringbuf::seekoff()
定義的一部分,它是一個虛擬成員函數。 std::basic_stringstream<char>
包含一個成員,該成員是std::basic_stringbuf
實例,其構造需要定義虛擬成員函數。
包括<sstream>
,您可以定義一個通用operator |
並將其引入全局名稱空間operator |
超載。 |
的操作數 上面的表達式僅包含非相關名稱。 因此,該表達式實際上不應受到operator |
因為決定使用哪個運算符應該在std::basic_stringbuf::seekoff()
的定義中首先遇到表達式的地方發生。 但是,據我所知,Visual C ++編譯器實際上只是將模板函數實例放在翻譯單元的末尾。 本身基於[temp.point] / 8是允許的。 但是,Visual C ++過去也將所有名稱查找延遲到模板實例化時間,這已記錄為非標准行為 。 沒有/permissive-
開關,編譯器仍將執行此非標准名稱查找作為兼容性功能。 然后它將找到並嘗試使用您的operator |
這是比內置運算符更好的匹配,因為兩個操作數都是枚舉類型,並且需要整數提升 。 使用/permissive-
,編譯器將執行正確的兩階段名稱查找,並正確決定使用內置|
運算符。
有一個/Zc:twoPhase-
標志對這個不規范的行為明確啟用時/permissive-
生效。 因此,您只需打開/permissive-
和/Zc:twoPhase-
並觀察到這會像預期的那樣帶回錯誤,就可以驗證問題實際上是由非標准名稱查找引起的。
除此之外,請注意您的operator |
不會返回值,因此,如果最終在任何地方實際使用此運算符,最終將導致調用未定義的行為…;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.