C.M.
C.M.

Reputation: 3383

Is MSVC correct in refusing to compile this code?

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

Answers (1)

HolyBlackCat
HolyBlackCat

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

Related Questions