編譯器警告 (層級 4) C4866
' file ( line_number )' 編譯器可能不會強制執行由左至右的評估順序來 呼叫 operator_name
備註
從 C++17 開始,運算子 的運算元 - > * 、 [] 、 >> 和 << 必須以由左至右的順序進行評估。 編譯器在兩種案例下無法保證此順序:
當其中一個運算元運算式是由值傳遞的物件或包含由值傳遞的物件,或
當使用 /clr 編譯且其中一個運算元事物件或陣列元素的欄位時。
編譯器在無法保證從左到右的評估時會發出警告 C4866。 只有在指定 或更新版本時 /std:c++17
,才會產生這個警告,因為 C++17 中引進了這些運算子的由左至右順序需求。
此警告預設為關閉;您可以使用 /Wall 或 /w N 4866 在命令列上將其啟用為層級 N 警告,或使用來源檔案中的 #pragma 警告。 如需詳細資訊,請參閱 預設 關閉的編譯器警告。
由於 C++17 標準的編譯器一致性工作,Visual Studio 2017 15.9 版引進了這個警告。 在 Visual Studio 2017 15.9 版之前,在編譯器版本中在沒有警告的情況下編譯的程式碼現在可以產生 C4866 。 如需如何停用特定編譯器版本或更新版本中引進的警告的相關資訊,請參閱 編譯器版本的 編譯器警告。
若要解決此警告,請先考慮是否需要運算子元素的由左至右評估,例如評估元素時,可能會產生順序相依的副作用。 在許多情況下,評估元素的順序不會有可觀察的效果。
如果評估順序必須由左至右,請考慮是否可以改為以傳址方式 const
傳遞元素。 此變更會消除下列程式碼範例中的警告。
範例
此範例會產生 C4866,並示範修正方法:
// C4866.cpp
// compile with: /w14866 /std:c++17
class HasCopyConstructor
{
public:
int x;
HasCopyConstructor(int x) : x(x) {}
HasCopyConstructor(const HasCopyConstructor& h) : x(h.x) { }
};
int operator->*(HasCopyConstructor a, HasCopyConstructor b) { return a.x + b.x; }
// This version of operator->* does not trigger the warning:
// int operator->*(const HasCopyConstructor& a, const HasCopyConstructor& b) { return a.x + b.x; }
int main()
{
HasCopyConstructor a{ 1 };
HasCopyConstructor b{ 2 };
a->*b; // C4866 for call to operator->*
};