将前向声明的类型转换为 void 是否合法?

Is it legal to cast a forward-declared type to void?

下面是一个C++头文件,在g++和clang下编译没有错误,但是在MSVC2015下,在(void) copyFrom行出错,错误为C2027: use of undefined type 'blah::SomeOtherClass'.

我的问题是:根据 C++ 标准,这段代码是否合法?或者,如果代码不正确(即因为将参数强制转换为 (void) 合法地需要的不仅仅是前向声明),那么在不引入 copyFrom 参数的情况下保留我的 DOxygen 文档的好方法是什么不需要的 parameter copyFrom was never referenced 警告进入我的编译器输出? (请注意,SomeOtherClass 的完整定义此时不可用,因为 SomeOtherClass 取决于 DummyImplementation

#ifndef blah_h
#define blah_h

namespace blah {

class SomeOtherClass;

/** Example of the problem at hand */
class DummyImplementation
{
public:
   /** Dummy implemention of CopyFrom().
    *  @param copyFrom This parameter is ignored.
    *  @returns zero.
    */
   int CopyFrom(const SomeOtherClass & copyFrom)
   {
      (void) copyFrom;  // error C2027: use of undefined type 'blah::SomeOtherClass'
      return 0;
   }
};

} // end namespace blah

#endif

更新:根据 Francois 的要求,这里是我的程序在使用 MSVC 19.0.24210.0 构建时使用的构建(不是关于 C++ 标准要求的问题的答案应该取决于特定的行为MSVC 版本):

cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline /nologo /MP 
/arch:SSE2 /Zi -O2 -MD -Zc:strictStrings -GR -W3 -w34100 -w34189 -w44996 
-EHsc -D_WIN32_WINNT=0x0601 -DNDEBUG -D__WIN32__ -D_USE_MATH_DEFINES 
-DQT_NO_CAST_ASCII -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
[... various -I flags omitted ...]

完整故事请参考回答。

根据 cppref,对于 (type-name) expression(强调我的)

If type-name is void, then expression is evaluated for its side-effects and its returned value is discarded, same as when expression is used on its own, as an expression statement.

也就是说,(void)copyFrom 等同于 copyFrom,后者没有任何作用,并且在 C++ 中不应要求完整类型。

顺便说一下,您的代码可以在 MSVC 2017 中正常编译 (live)。

要抑制编译警告,您可以考虑:

std::addressof(copyFrom)