Reputation: 3383
Consider this code (godbolt):
#include <type_traits>
#include <memory>
#include <cstdlib>
using namespace std;
template<auto L, class T = decltype(L)>
using constant = integral_constant<T, L>;
int main()
{
unique_ptr<void, constant<&free>> p1;
unique_ptr<void, constant<free>> p2; // <-- MSVC refuses to compile this line
return 0;
}
Why does MSVC refuse to compile the highlighted line? Is this code valid?
MSVC produces:
<source>(13): error C2975: 'L': invalid template argument for 'constant', expected compile-time constant expression
<source>(7): note: see declaration of 'L'
Upvotes: 4
Views: 175
Reputation: 96043
Pre-C++20 it looks like a MSVC bug.
After C++20, the behavior is unspecified (thanks @heapunderrun)
since free
is not in the list of functions you're allowed to take the addresses of. But I'd argue that it's still a bug (even if conformant), since MSVC lets you take the address of the same function if you use &
.
Template argument deduction in this case is done as if by constexpr auto x = free;
([temp.arg.nontype]/1
), and the above declaration is accepted by MSVC, deducing a function pointer.
Some implicit conversions are banned when passing a template argument, the allowed conversions are listed in [expr.const]/10
and include a "function-to-pointer conversion".
Upvotes: 3