在下面的程序函数中
foo
返回一个结构体模板特化A<int>
:
template<typename T> struct A {};
A<int> foo();
int main() {
foo(); //MSVC warning here
}
A<int> foo() { return {}; }
带有命令行标志
/Wall
的 Visual Studio 编译器在调用 foo()
的地方发出警告:
warning C4686: 'foo': possible change in behavior, change in UDT return calling convention
根据 Microsoft 文档中的 编译器警告 C4686
类模板特化在用于返回类型之前未定义。
在我的例子中,结构模板是之前定义的。之后仅定义函数本身(在现实生活中,函数是在另一个 .cpp 文件中定义的)。
即使使用-Wall -Wextra -pedantic-errors
标志,GCC 和 Clang 也看不到程序中有任何不好的地方。在线演示:https://gcc.godbolt.org/z/1o9cTGn4j
代码有问题吗?可以在没有
#pragma warning(disable:4686)
的情况下以某种方式消除警告吗?
使用模板特化作为返回类型不需要实例化(也不应该,见下文)。但是,影响 UDT 返回调用约定的属性只有在定义返回类型之后才知道,并且模板专门化仅在实例化时定义。
要修复警告,您可以强制实例化模板专门化。
因此,解决方案是通过添加以下行来显式实例化模板化返回类型:
template A<int>;