Given the following test code:
void Serialize(std::ostream& os, int& i)
{
os << "int: " << i << '\n';
}
template<typename T>
void Write(std::ostream& os, T* pData)
{
::Serialize(os, *pData);
}
struct SData
{
int i = 42;
};
void Serialize(std::ostream& os, SData& rData)
{
os << "SData: " << rData.i << '\n';
}
void Test()
{
auto os = std::ofstream("c:/test.out");
auto s = SData();
Write(os, &s);
}
int main([[maybe_unused]] int, [[maybe_unused]] char*[])
{
Test();
}
The MSVC compiler with /permissive-
(compiler set to standards conformance mode) fails to compile this as only the Serialize
free function(s) declared prior to the the function template definition are visible to the function template.
The above compiles fine with the MSVC compiler either using /permissive
(standards conformance mode disabled) or removing the global scope operator on the Serialize
call.
The above also compiles fine when using the LLVM (clang-cl) toolset in VS 2022, or using clang++.
I would expect that the lookup occurs at the point that the function template is instantiated, and it appears that this is not the case with MSVC using /permissive-
. Microsoft replied to my community post that this is not a bug. I'd like to know why this is expected behavior.