Consider this code:
using func = int (*)(int, int);
template<func F>
void do_something(int first, int second) {}
int something(int first, int second) { return 42; }
void f()
{
constexpr auto function = something;
do_something<function>(10, 20);
}
Which is compiled and run with C++17 standard compatible compiler, but it's fail with C++11 standard:
error: no matching function for call to ‘do_something<function>(int, int)’
17 | do_something<function>(10, 20);
What is the difference between C++11 non-type template parameters and C++17 non-type template parameters? in §14.1.4 [temp.param][n3690]:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
— integral or enumeration type,
— pointer to object or pointer to function,
— lvalue reference to object or lvalue reference to function,
— pointer to member,
— std::nullptr_t.
And in §17.1.4 [temp.param][n4713]:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
(4.1) — integral or enumeration type,
(4.2) — pointer to object or pointer to function,
(4.3) — lvalue reference to object or lvalue reference to function,
(4.4) — pointer to member,
(4.5) — std::nullptr_t, or
(4.6) — a type that contains a placeholder type (10.1.7.4).
The only difference is:
< — a type that contains a placeholder type (10.1.7.4).
Which I don't think is related to my question because a placeholder type is something like auto
, and I sent a value to template not a placeholder type or a type.
constexpr auto function = &something;
? – Endometrium&something
directly into the invocationdo_something<&function>(10, 20)
then all is well? – Endometriumint something(int first, int second) {}
– Endometriumdo_something<&function>(1, 1);
and... function = &something; do_something<&function>(1, 1);
, but nothing changed. – Petitiondo_something<&something>(10, 20);
should work fine, proving the failure is related to theconstexpr
variable – Endometriumdo_something<&something>(1, 1);
ordo_something<something>(1, 1);
. – Petition