編譯器警告 (層級 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->*
};