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

Jer*_*ner 3 c++ doxygen forward-declaration visual-c++ language-lawyer

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

我的问题是:根据C++标准,此代码是否合法?或者如果代码不正确(即因为将参数转换为(void)合法地需要的不仅仅是前向声明),那么保留我的DOxygen文档以获得copyFrom参数的好方法是什么,而不会在parameter copyFrom was never referenced我的编译器中引入不必要的警告-Output?(注意,此时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
Run Code Online (Sandbox Code Playgroud)

更新:Per 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 ...]
Run Code Online (Sandbox Code Playgroud)

Lin*_*gxi 5

有关完整的故事,请参阅答案.

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

如果type-namevoid,则expression评估其副作用,并且丢弃其返回值,expression单独使用时相同,作为表达式语句.

也就是说,(void)copyFrom相当于copyFrom没有效果,并且不应该要求C++中的完整类型.

顺便说一下,你的代码可以很好地使用MSVC 2017(实时).

要禁止编译器警告,您可以考虑:

std::addressof(copyFrom)
Run Code Online (Sandbox Code Playgroud)